def test_method
["a", "b", "c"].map {|i| yield(i) }
end
如果我这样调用test_method:
p test_method {|i| i.upcase }
# => ["A", "B", "C"]
为什么我需要块内的{| i |},而不只是这样说:
p test_method { i.upcase }
我之所以这么认为是因为在test_method中调用yield时,我们已经有{| i |}
["a", "b", "c"].map {|i| yield(i) }
答案 0 :(得分:3)
如果你来自Groovy背景,他们有一个隐式迭代器,甚至来自Scala,你可以在没有这个的情况下使用| i |使用部分函数,然后你可能会发现它是一个逻辑问题,但是,目前在Ruby 1.9或者甚至在Rails中你可以做的最好的事情是使用像JRL所提到的Symbol#to_block方法:
p test_method &:upcase
只需在方法名称前添加&:。
答案 1 :(得分:2)
块需要参数化值才能传递给upcase方法。它可以这样看:如果你省略了| i |在块中,它无法“捕获”所产生的值(i在test_method中)
答案 2 :(得分:2)
在Ruby 1.9中,你可以写:
p test_method &:upcase
答案 3 :(得分:2)
正如ennuikiller所说,您必须定义您希望命名从yield
语句传回的变量的名称。这与变量的范围有关。传递给test_method
的块内部的范围不知道i
变量。你可以随意调用它。
例如,您可以执行以下操作:
def test_method
["a", "b", "c"].map { |i| yield(i) }
end
p test_method { |some_variable_name| some_variable_name.upcase }
仅仅因为测试方法知道它,并不意味着传递给测试方法的块将知道它。
修改1:要提供更多信息,如果它更清晰一点,您可以按照以下方式重新定义test_method
:
def test_method(&block)
if not block.nil?
["a", "b", "c"].map { |i| yield(i) }
end
end
答案 4 :(得分:0)
当你打电话
p test_method {|i| i.upcase}
方法定义中使用的|i|
不可见(其范围仅在{}
内。
特别是您正在构建一个采用单个变量的块,要构建该块,您必须指定该变量。注意
p test_method {|j| j.upcase}
也有效。