我在Coppers的书“Beginning Ruby”中找到了这个代码块的例子。这应该是处理代码块的自定义方法的一个例子吗?
def each_vowel(&code_block)
%w{a e i o u}.each { |vowel| code_block.call(vowel) }
end
each_vowel { |vowel| puts vowel }
我只是看不出这是如何工作的。他是否将代码块发送到另一个代码块?
关于它的一些事情感觉不对劲。我得到each
从数组中获取特定项目,一次一个,并将其放入vowel
变量,但接下来会发生什么?
答案 0 :(得分:2)
%w{a e i o u}
是一系列单词的ruby syntax。它相当于['a', 'e', 'i', 'o', 'u']
。
所以上面的代码可以写成:
def each_vowel(&code_block)
['a', 'e', 'i', 'o', 'u'].each { |vowel| code_block.call(vowel) }
end
each_vowel { |vowel| puts vowel }
所以这段代码的作用是对于数组中的每个元素(.each
),它以元素作为参数调用块(code_block.call
)。
.each
本身接受一个块(在本例中为{ |vowel| code_block.call(vowel) }
),并为数组中的每个元素调用它。
行each_vowel { |vowel| puts vowel }
使用块{ |vowel| puts vowel }
作为输入参数调用前面定义的方法。它可能更熟悉括号:
each_vowel() { |vowel| puts vowel }
但是在ruby括号中是可选的,特别是当方法不期望参数时(块不计为参数)。
答案 1 :(得分:2)
是的,你是对的,正在另一个块内执行一个块。 &code_block
是将块转换为可执行proc对象的特殊方法。在方法定义中,code_block
现在引用一个proc对象,当使用call方法执行时,它基本上运行与方法调用相关的块中的代码(在本例中为{ |vowel| puts vowel }
。
这不是执行相关块的唯一方法。另一种非常常见的方法是使用yield关键字。这里,只要达到yield关键字,就会执行该块。
def each_vowel
%w{a e i o u}.each { |vowel| yield(vowel) }
end
each_vowel { |vowel| puts vowel }
请注意,在这种情况下,不必在方法签名中使用&code_block
。 Yield始终可以访问相关块。但是,如果要以proc对象的形式访问块,则需要在参数列表的末尾指定&code_block
之类的内容。