Code block from Ruby book
我在Coppers的书《开始的Ruby》中找到了一个代码块的例子。这应该是处理代码块的自定义方法的示例吗?
1 2 3 4 5
| 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变量中,但是接下来会发生什么呢?
是的,在另一个块中执行一个块是正确的。&code_block是一种将块转换为可执行proc对象的特殊方法。在方法定义中,code_block现在引用一个proc对象,当使用call方法执行时,该对象基本上运行与方法调用关联的块中的代码(在本例中是{ |vowel| puts vowel }。
但这不是执行关联块的唯一方法。另一种非常常见的方法是使用yield关键字。在这里,一旦到达yield关键字,就执行块。
1 2 3 4 5
| 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的内容。
- 所以在元音屈服(元音)中,我们将元音作为参数传递给代码块。所以它会把A,E,I,O,U
- 是的,没错。我们传递给收益率的任何内容都将作为{ |vowel| puts vowel }块的参数传递。由于yield(vowel)被称为五次(每个元音一次),所以{ |vowel puts vowel}也被称为五次,每次都将另一个字母传递给vowel参数。在您的示例中,code_block.call(vowel)执行完全相同的操作。
- 一个乐天的家伙:)
- 没问题。你举了一个有趣的例子。如果你的答案中有一个能满足你的问题,如果你能接受它,那就太棒了。
- 抱歉,忘记了,我只是点击了一下。)
%w{a e i o u}是单词数组的Ruby语法。相当于['a', 'e', 'i', 'o', 'u']。
所以上面的代码可以写成:
1 2 3 4 5
| 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 }作为输入参数。它可能更熟悉括号:
1
| each_vowel() { |vowel| puts vowel } |
号
但是在Ruby中,括号是可选的,特别是当一个方法不需要参数时(一个块不算参数)。
- 我明白了,但我看不出这一节中的内容元音代码块。呼叫(元音)
- @用户38677776-我已经添加了更多的解释。如果你发现什么东西还不清楚,请告诉我,它在哪里为你崩溃。
- each { |vowel| ... }与带forEach(function(vowel) { ... })的javascript非常相似。只需将它看作一个具有稍微不同的定义方法的内联函数。
- 想象一下,你是一个绰号为"cap"的code_block,因为你唯一知道怎么做的就是把一个字符串大写。人们会喊出这样的话:"嘿,帽子,我用‘E’能得到什么?"你做你的事,然后大喊:"那就是‘E’"。在背景中,你听到有人喊道:"哟,西西,我能得到什么‘神器’?"然后回答:"八!".