我正在做一些Ruby Koan练习。因为我是一个新手,所以有些代码对我来说似乎没有意义。例如,参数前面的&
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
为什么在&
和block
之前有add_one
?要使它们成为全局变量或将它们引用到前一个变量?
谢谢!
答案 0 :(得分:3)
在方法定义中的参数前面,一元前缀&符号&
sigil表示:将传递给此方法的块打包为适当的Proc
对象。
在方法调用中的参数前面,一元前缀&符号&
运算符意味着:通过向对象发送消息,将作为参数传递的对象转换为Proc
to_proc
(除非它已经是Proc
)并将其“展开”到一个区块中,即将Proc
视为直接作为一个区块直接传递。
答案 1 :(得分:1)
procs的例子
multiples_of_3 = Proc.new do |n|
n%3 == 0
end
(1..100).to_a.select(&multiples_of_3)
"&"这里用于将proc转换为块。
另一个例子 这是你如何将块(而不是局部变量)的引用传递给方法。 Ruby允许您将任何对象传递给方法,就好像它是一个块一样。该方法将尝试使用传入的对象,如果它已经是一个块,但如果它不是块,它将调用to_proc,试图将其转换为块。
另请注意,块部分(没有&符号)只是引用的名称,如果它对您更有意义,您可以使用您喜欢的任何名称。
def my_method(&block)
puts block
block.call
end
my_method { puts "Hello!" }
#<Proc:0x0000010124e5a8@tmp/example.rb:6>
Hello!
正如您在上面的示例中所看到的,my_method中的块变量是对块的引用,可以使用call方法执行。对块的调用与使用yield相同,有些人喜欢使用block.call而不是yield来获得更好的可读性。