Ruby书中的代码块

时间:2014-11-26 18:48:22

标签: ruby

我在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变量,但接下来会发生什么?

2 个答案:

答案 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之类的内容。