Ruby 中 [1,2,3].to_enum 和 [1,2,3].enum_for 的区别
Posted
技术标签:
【中文标题】Ruby 中 [1,2,3].to_enum 和 [1,2,3].enum_for 的区别【英文标题】:Differences between [1,2,3].to_enum and [1,2,3].enum_for in Ruby 【发布时间】:2014-07-14 01:32:40 【问题描述】:在 Ruby 中,我试图了解 to_enum
和 enum_for
方法之间的关系。在我提出问题之前,我已经提供了一些示例代码和两个示例来帮助了解上下文。
示例代码:
# replicates group_by method on Array class
class Array
def group_by2(&input_block)
return self.enum_for(:group_by2) unless block_given?
hash = Hash.new |h, k| h[k] = []
self.each |e| hash[ input_block.call(e) ] << e
hash
end
end
示例#1:
irb (main)> puts [1,2,3].group_by2.inspect
=> #<Enumerator: [1, 2, 3]:group_by2>
在示例 #1 中:在数组 [1,2,3]
上调用 group_by
,而不传入块,返回使用命令 self.enum_for(:group_by_2)
生成的枚举器。
示例 #2
irb (main)> puts [1,2,3].to_enum.inspect
=> #<Enumerator: [1, 2, 3]:each>
在示例 #2 中,枚举数是通过在数组 [1,2,3]
上调用 to_enum
方法生成的
问题:
在示例 1 和 2 中生成的枚举器是否以任何方式表现不同?我可以从检查的输出中看到它们显示的标签略有不同,但我可以发现枚举器的行为有任何差异。
# Output for example #1
#<Enumerator: [1, 2, 3]:each> # label reads ":each"
# Output for example #2
#<Enumerator: [1, 2, 3]:group_by2> # label reads ":group_by2"
【问题讨论】:
【参考方案1】:p [1, 2, 3].to_enum
p [1, 2, 3].enum_for
--output:--
#<Enumerator: [1, 2, 3]:each>
#<Enumerator: [1, 2, 3]:each>
来自文档:
to_enum
创建一个新的枚举器,它将通过调用方法来枚举 obj,如果有的话,传递 args。
...
enum_for
创建一个新的枚举器,它将通过调用方法来枚举 obj,如果有的话,传递 args。
ruby 是一种语言,其方法名称通常是同义词。
后续问题:
命令 [1,2,3].to_enum(:foo) 中的符号是否有作用, 除了在输出中用 :foo 替换 :each 吗?
是的。默认情况下,ruby 将枚举器连接到接收器的 each() 方法。有些类没有each() 方法,例如String:
str = "hello\world"
e = str.to_enum
puts e.next
--output:--
1.rb:3:in `next': undefined method `each' for "helloworld":String (NoMethodError)
from 1.rb:3:in `<main>
to_enum() 允许您指定希望枚举器使用的方法:
str = "hello\nworld"
e = str.to_enum(:each_line)
puts e.next
--output:--
hello
现在,假设您有数组[1, 2, 3]
,并且您想为您的数组创建一个枚举器。数组有一个 each() 方法,但不是用 each() 创建一个枚举器,它将返回数组中的每个元素,然后结束;你想创建一个枚举器,一旦到达数组的末尾就从数组的开头重新开始?
e = [1, 2, 3].to_enum(:cycle)
10.times do
puts e.next()
end
--output:--
1
2
3
1
2
3
1
2
3
1
【讨论】:
@ 7stud 谢谢。只是想确保我没有遗漏什么。 @amorphid, ruby 文档曾经很擅长说,“这个方法是方法 A 的同义词。参见方法 A 的描述。”我宁愿看到那个推荐而不是重复的描述。 我刚刚重读了您的示例,刚刚意识到也可以执行[1,2,3].to_enum(:foo)
,它返回#<Enumerator: [1, 2, 3]:foo>
。如果我意识到这一点,我的问题只是 => 命令[1,2,3].to_enum(:foo)
中的符号是否有目的,而不是在输出中用:foo
替换:each
? docs for the Enumerator class 对此只字不提,至少我看不到。
@amorphid,我编辑了我的帖子来回答你的后续问题。
谢谢。这正是我一直在寻找的答案!我花了一点时间才弄清楚如何提出这个问题:)以上是关于Ruby 中 [1,2,3].to_enum 和 [1,2,3].enum_for 的区别的主要内容,如果未能解决你的问题,请参考以下文章
ruby-2.4.6和redis-4.1.3.gem环境下的redis-cluster集群中的bug