2016-03-01 47 views
1

我正在做一些Ruby Koan练习。由于我是一个新手,所以有些代码对我来说似乎没有意义。例如,在一个参数在Ruby中的参数前做了什么?

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 

前面的&为什么有blockadd_one&?使它们成为全局变量或将它们引用到以前的变量中?

谢谢!

+0

你基本上是通过一段代码作为参数,当在你的方法中使用'call'时,你在调用那个块并在那里使用它。因此,您可以看到'method_with_explicit_block({| n | n * 2})',您正在调用此方法并传递该块参数。在方法'method_with_explicit_block'中,你可以看到它被称为'block.call(10)',并且一个参数为'10'被传递给该块。在块{{| n | n * 2}','n = 10'在这种情况下。由于该块调用是该方法中的最后一行,该块的结果将返回。 –

回答

3

在方法定义一个参数的前面,一元前缀符号&印记是指:包传递给此方法作为合适Proc对象块。

在方法调用一个参数的前面,一元前缀符号&操作是指:通过发送它的消息to_proc(除非它已是一个Proc)和“展开作为一个参数传递的对象转换为Proc “它变成了一个块,即将Proc视为块,而不是直接作为块传递。

1

实施例特效

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:[email protected]/example.rb:6> 
Hello! 

正如可以在上面的示例中看到的,内my_method块变量是对块的参考,它可以与该呼叫方法来执行。调用块与使用yield相同,有些人喜欢使用block.call而不是yield来提高可读性。

相关问题