`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 上。我在 pry
和 ruby -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
任何东西。
为什么这个枚举器意外地 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 上。我在 pry
和 ruby -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
任何东西。