枚举器如何接收块?

时间:2017-05-11 23:29:30

标签: ruby iterator

我有:

letters = %w(e d c b a)

以下内容:

letters.group_by.each_with_index { |item, index| index % 3 }
#=> {0=>["e", "b"], 1=>["d", "a"], 2=>["c"]}

group_by返回的枚举器如何知道它将执行的块? each_with_index收到的块是否传递给它所基于的枚举器?

以下内容:

letters.each_with_index.group_by { |item, index| index % 3 }
#=> {0=>[["e", 0], ["b", 3]], 1=>[["d", 1], ["a", 4]], 2=>[["c", 2]]}

是否会将块传递给each_with_index返回的枚举器?如果愿意,each_with_index如何执行它?

一般来说:

  1. 如何通过枚举器中的方法检索不直接接收块的块?
  2. 块是否会通过枚举链传递?它将在何处执行?

1 个答案:

答案 0 :(得分:2)

这里有一些棘手的事情,所以这可能就是为什么你对它的工作方式有点模糊。枚举器是Ruby中最重要的东西之一,它们是可枚举系统的支柱,这是Ruby真正发挥作用的地方,但它们经常以他们透明的方式使用,生活在阴影,所以你很少需要直接关注它们。

仔细观察,逐步逐步完成:

letters.group_by
# => #<Enumerator: ["e", "d", "c", "b", "a"]:group_by>

现在这是一个Enumerator实例。您链接的each_with_index实际上是枚举器特定的方法:

letters.group_by.method(:each_with_index)
# => #<Method: Enumerator#each_with_index>

这与您的第二种方法形成对比:

letters.method(:each_with_index)
# => #<Method: Array(Enumerable)#each_with_index>

那个是Array的方法,方便的是,你可以链接到像group_by这样的方法。

所以这里的故事是链式模式中的group_by实际上提供了特殊方法,可以将块反向传播到group_by级别。