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 an if / else clause?

+3


source to share


2 answers


*

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

If args = [1, 2, 3]

, then:

  • f[args]

    equivalent f[ [1, 2, 3] ] #There is one argument: an array.

  • f[*args]

    equivalent f[1, 2, 3] #There are three arguments.

If it f[*args]

returns [4, 5, 6]

, then:



  • self[f[*args]]

    equivalent self[ [4, 5, 6] ] #self is called with 1 arg.

  • self[*f[*args]]

    equivalent self[4, 5, 6] #self is called with 3 args.

An example *

used to collect items in an array is:

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

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

.

+5


source


*

(also known as splat) allows you to call a method with an array of arguments rather than passing values ​​individually. If you settled on splat then ruby ​​will just pass one value (it will be an array). This unary is *

not an operation *

that this code defines as an aliascompose

The if branch self

has an arty of 1, then f

should return a single value and therefore no need for splat.



The else branch self

accepts multiple arguments, which means it f

should return an array of values, and splat is used to call self

with those arguments.

0


source







All Articles