为什么要使用to_enum方法而不是直接使用对象,在Ruby中创建对象的代理引用?我想不出任何实际用途,试图理解这个概念以及有人可能会使用它的地方,但我看到的所有例子都显得非常微不足道.
例如,为什么使用:
"hello".enum_for(:each_char).map {|c| c.succ }
Run Code Online (Sandbox Code Playgroud)
代替
"hello".each_char.map {|c| c.succ }
Run Code Online (Sandbox Code Playgroud)
我知道这是一个非常简单的例子,有没有人有任何现实世界的例子?
Mar*_*une 14
接受块的大多数内置方法将返回枚举器,以防没有提供块(如String#each_char
您的示例中所示).对于这些,没有理由使用to_enum
; 两者都会产生同样的效果.
但是,有些方法不会返回枚举器.在这种情况下,您可能需要使用to_enum
.
# How many elements are equal to their position in the array?
[4, 1, 2, 0].to_enum(:count).each_with_index{|elem, index| elem == index} #=> 2
Run Code Online (Sandbox Code Playgroud)
再举一个例子,Array#product
,#uniq
和#uniq!
过去不接受块.在1.9.2中,这已被更改,但为了保持兼容性,没有块的表单无法返回Enumerator
.人们仍然可以"手动"使用to_enum
来获取枚举器:
require 'backports/1.9.2/array/product' # or use Ruby 1.9.2+
# to avoid generating a huge intermediary array:
e = many_moves.to_enum(:product, many_responses)
e.any? do |move, response|
# some criteria
end
Run Code Online (Sandbox Code Playgroud)
主要用途to_enum
是在实现自己的迭代方法时.您通常会将第一行作为第一行:
def my_each
return to_enum :my_each unless block_given?
# ...
end
Run Code Online (Sandbox Code Playgroud)
这并不完全是您问题的答案,但希望它是相关的。
在第二个示例中,您each_char
在不传递块的情况下进行调用。当没有块调用时each_char
返回一个,Enumerator
所以你的例子实际上只是做同一件事的两种方法。(即两者都会导致创建可枚举对象。)
irb(main):016:0> e1 = "hello".enum_for(:each_char)
=> #<Enumerator:0xe15ab8>
irb(main):017:0> e2 = "hello".each_char
=> #<Enumerator:0xe0bd38>
irb(main):018:0> e1.map { |c| c.succ }
=> ["i", "f", "m", "m", "p"]
irb(main):019:0> e2.map { |c| c.succ }
=> ["i", "f", "m", "m", "p"]
Run Code Online (Sandbox Code Playgroud)