简体   繁体   中英

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?

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 .

* (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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM