Ruby中[1,2,3] .to_enum和[1,2,3] .enum_for之间的差异

时间:2014-05-24 22:55:03

标签: ruby enumeration enumerable

在Ruby中,我试图了解to_enumenum_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中:在数组group_by上调用[1,2,3]而不传入块,返回使用命令self.enum_for(:group_by_2)生成的枚举器。

示例#2

irb (main)> puts [1,2,3].to_enum.inspect
=> #<Enumerator: [1, 2, 3]:each> 

在示例#2中,通过调用数组to_enum上的[1,2,3]方法生成枚举器

问题:

在示例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 个答案:

答案 0 :(得分:10)

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?

是。默认情况下,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