Dan Jenson
Dan Jenson

Reputation: 1041

How does the compose (*) function work in Ruby (from The Ruby Programming Language)?

Excerpt The Ruby Programming Language:

module Functional
  def compose(f)
    if self.respond_to?(:arity) && self.arity == 1
      lambda {|*args| self[f[*args]] }
    else
      lambda {|*args| self[*f[*args]] }
    end
  end
  alias * compose
end

class Proc; include Functional; end
class Method; include Functional; end

f = lambda {|x| x * 2 }
g = lambda {|x, y| x * y}
(f*g)[2, 3] # => 12

What is the difference between f and *f in the if/else clause?

Upvotes: 3

Views: 1169

Answers (2)

7stud
7stud

Reputation: 48649

The * either collects all the items into an array, or explodes an array into individual elements--depending on the context.

If args = [1, 2, 3], then:

  • f[args] is equivalent to f[ [1, 2, 3] ] #There is one argument: an array.
  • f[*args] is equivalent to f[1, 2, 3] #There are three arguments.

If f[*args] returns [4, 5, 6], then:

  • self[f[*args]] is equivalent to self[ [4, 5, 6] ] #self is called with 1 arg.
  • self[*f[*args]] is equivalent to self[4, 5, 6] #self is called with 3 args.

An example of * being used to collect items into an Array is:

  • lambda {|*args| ....}

You can call that function with any number of arguments, and all the arguments will be collected into an array and assigned to the parameter variable args.

Upvotes: 5

Frederick Cheung
Frederick Cheung

Reputation: 84182

* (also known as splat) allows you to call a method with an array of arguments rather than passing the values individually. If you left off the splat then ruby would just pass a single value (that happens to be an array). This unary * is not the * operation that this code defines as an alias of compose

In the if branch self has an arity of 1, then f should be returning a single value and so there is no need for the splat.

In the else branch self takes more than one argument, it follows that f should return an array of values, and the splat is used to call self with those arguments.

Upvotes: 0

Related Questions