`File.enum_for(:readlines, ...)` 不枚举

`File.enum_for(:readlines, ...)` not enumerating

为什么这个枚举器意外地 return 一个空数组:

> File.enum_for(:readlines, '/usr/share/dict/words').take(1)
=> []

虽然这个return正确:

File.enum_for(:readlines, "/usr/share/dict/words").each{}.take(1)
=> ["A\n"]

相比之下,其他枚举器在没有 each 的情况下也能工作:

> "abc".enum_for(:each_byte).take(1)
=> [97]

File.readlines 案例中真正奇怪的是 each 的主体实际上并没有被执行:

File.enum_for(:readlines, "/usr/share/dict/words").
     each{|e| p e; raise "stop" }.take(2)
=> ["A\n", "a\n"]

这是在 ruby 2.5.3 上。我在 pryruby -e 单行代码中都尝试了代码,结果相同。

显然 enum_for/to_enum 仅适用于 yield 的方法。感谢@Anthony 让我意识到这一点。

这相当于我尝试做的事情:

# whoops, `to_a` doesn't yield
[1,2,3].enum_for(:to_a).take(1)
=> []

# Works, but `enum_for` isn't really meant for this, and it's very possible this should be
#  considered undefined behavior.
# In this case, as in `File.readlines`, the `each` block isn't really executed.
> [1,2,3].enum_for(:to_a).each{}.take(1)
=> [1]

另一个有趣的事情是,在其中一个 "weird enumerators" 上调用 each{} 似乎就像直接调用枚举方法(例如 to_a)一样。但当然这是毫无意义的。

> arr = [1,2,3]
> arr.object_id
=> 70226978129700
> arr.to_a.object_id
=> 70226978129700
# same as calling `to_a` - doesn't create a new array!
> arr.enum_for(:to_a).each{}.object_id
=> 70226978129700

File.readlines 的情况下,它的实现只是简单地读入行和 returns 它们在一个数组中;它没有 yield 任何东西。