链接产生多个参数的枚举器

Ben*_*ann 9 ruby block enumerators

我试图弄清楚Ruby如何处理产生多个参数的链接枚举器.看一下这个片段:

a = ['a', 'b', 'c']

a.each_with_index.select{|pr| p pr}
# prints:
# ["a", 0]
# ["b", 1]
# ["c", 2]

a.each_with_index.map{|pr| p pr}
# prints:
# "a"
# "b"
# "c"
Run Code Online (Sandbox Code Playgroud)

为什么select将参数作为数组生成,而将map它们作为两个单独的参数生成?

iai*_*ain 5

尝试:

a.each_with_index.map{|pr,last| p "pr: #{pr} last: #{last}"}
Run Code Online (Sandbox Code Playgroud)

map自动解构传递给它的值.接下来的问题是它为什么要解构而select不是?

如果你看一下在Rdoc页面上给出的数组,它们实际上是相同的,select只是区别在于它对产生的值进行了测试.其他地方肯定会发生一些事情.

如果我们看一下Rubinius的来源(主要是因为我对Ruby比C更好;)map(别名collect),它告诉我们:

each do |*o|
Run Code Online (Sandbox Code Playgroud)

所以它正在通过的方式展开参数,而select(别名来自find_all)不会:

each do
Run Code Online (Sandbox Code Playgroud)

再次,设计决定为什么超出我.你必须找出谁写了它,也许问Matz :)


我要补充,看着Rubinius的源再次,map实际的提示图标上each yield,我不明白为什么你会怎么做时,双方只需要屈服图示:

  each do |*o|
    ary << yield(*o)
  end
Run Code Online (Sandbox Code Playgroud)

select不是.

each do
  o = Rubinius.single_block_arg
  ary << o if yield(o)
end
Run Code Online (Sandbox Code Playgroud)


Bor*_*cky 3

从目前的讨论来看,我们可以分析源代码,但我们不知道为什么。Ruby 核心团队的反应相对非常积极。我建议您登录http://bugs.ruby-lang.org/issues/并在那里发布错误报告。他们肯定会最多在几周内查看这个问题,并且您可能会期望它在 Ruby 的下一个小版本中得到纠正。(也就是说,除非有我们未知的设计原理来保持事物原样。)