A syntax problem about Ruby:
p = lambda &:upcase
p.call('a') ## A
Why it is valid? Where does this 'upcase' come from?
I think there is not a parameter which should be sent to upcase
, bug why this proc can have a parameter?
The first parameter is the receiver.
lambda(&:upcase)
is a shorthand for
lambda { |x| x.upcase }
just like
lambda(&:+)
is a shorthand for
lambda { |x, y| x.+(y) }
More correctly, &x
in an argument will call x.to_proc
; Symbol#to_proc
happens to return the above. For example, this is the definition of Symbol#to_proc
from Rubinius source:
class Symbol
# Returns a Proc object which respond to the given method by sym.
def to_proc
# Put sym in the outer enclosure so that this proc can be instance_eval'd.
# If we used self in the block and the block is passed to instance_eval, then
# self becomes the object instance_eval was called on. So to get around this,
# we leave the symbol in sym and use it in the block.
#
sym = self
Proc.new do |*args, &b|
raise ArgumentError, "no receiver given" if args.empty?
args.shift.__send__(sym, *args, &b)
end
end
end
As you can see, the resultant Proc
will shift off the first argument to act as receiver, and pass on the rest of the arguments. Thus, "a"
is the receiver, and the "a".upcase
thus gets an empty parameter list.