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