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

pop*_*nja 5 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
Run Code Online (Sandbox Code Playgroud)

示例#1:

irb (main)> puts [1,2,3].group_by2.inspect
=> #<Enumerator: [1, 2, 3]:group_by2> 
Run Code Online (Sandbox Code Playgroud)

在示例#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> 
Run Code Online (Sandbox Code Playgroud)

在示例#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"
Run Code Online (Sandbox Code Playgroud)

7st*_*tud 10

p [1, 2, 3].to_enum
p [1, 2, 3].enum_for

--output:--

#<Enumerator: [1, 2, 3]:each>
#<Enumerator: [1, 2, 3]:each>
Run Code Online (Sandbox Code Playgroud)

来自文档:

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>
Run Code Online (Sandbox Code Playgroud)

to_enum()允许您指定您希望枚举器使用的方法:

str = "hello\nworld"
e = str.to_enum(:each_line)
puts e.next

--output:--
hello
Run Code Online (Sandbox Code Playgroud)

现在,假设您有阵列[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
Run Code Online (Sandbox Code Playgroud)

  • @amorphid,ruby docs曾经说得很好,"这个方法是方法A的同义词.请参阅方法A的描述." 我宁愿看到推荐而不是重复的描述. (2认同)