Reputation: 1280
I'm doing some Ruby Koan exercises. Since i'm quite a newbie, so some code doesn't seem to make sense for me. For example, the &
in front of an argument
def method_with_explicit_block(&block)
block.call(10)
end
def test_methods_can_take_an_explicit_block_argument
assert_equal 20, method_with_explicit_block { |n| n * 2 }
add_one = lambda { |n| n + 1 }
assert_equal 11, method_with_explicit_block(&add_one)
end
Why there's a &
before block
and add_one
? To make them global variables or refer them to the previous variable?
Thank you!
Upvotes: 8
Views: 1931
Reputation: 1606
Example in case of procs
multiples_of_3 = Proc.new do |n|
n%3 == 0
end
(1..100).to_a.select(&multiples_of_3)
The "&" here is used to convert proc into block.
Another Example It’s how you can pass a reference to the block (instead of a local variable) to a method. Ruby allows you to pass any object to a method as if it were a block. The method will try to use the passed in object if it’s already a block but if it’s not a block it will call to_proc on it in an attempt to convert it to a block.
Also note that the block part (without the ampersand) is just a name for the reference, you can use whatever name you like if it makes more sense to you.
def my_method(&block)
puts block
block.call
end
my_method { puts "Hello!" }
#<Proc:0x0000010124e5a8@tmp/example.rb:6>
Hello!
As you can see in the example above, the block variable inside my_method is a reference to the block and it can be executed with the call method. call on the block is the same as using yield, some people like to use block.call instead of yield for better readability.
Upvotes: 2
Reputation: 369624
In front of a parameter in method definition, the unary prefix ampersand &
sigil means: package the block passed to this method as a proper Proc
object.
In front of an argument in method call, the unary prefix ampersand &
operator means: convert the object passed as an argument to a Proc
by sending it the message to_proc
(unless it already is a Proc
) and "unroll" it into a block, i.e. treat the Proc
as if it had been passed directly as a block instead.
Upvotes: 7