ruby 1.8.7 to_proc创建空数组 [英] ruby 1.8.7 to_proc creates empty arrays

查看:155
本文介绍了ruby 1.8.7 to_proc创建空数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是此答案的后续内容,该内容涉及ruby 1.8.7的Symbol#to_proc生成新的proc每次调用.

This is a follow-up to to this answer, regarding ruby 1.8.7's Symbol#to_proc generating a new proc every invocation.

发生的事情似乎比答案所提示的要多.

There seems to be more going on than the answers suggest.

以下是一些示例代码:

def ctob
  h=Hash.new(0)
  ObjectSpace.each_object(Object) {|e| h[e.class]+=1 }
  h
end
r=(0...1000)
p ctob
r.map(&:to_i)
p ctob

这表明正在创建大约一千个数组.这表明大约有一千个空白:

This reveals that about a thousand arrays are being created. This reveals that about a thousand are empty:

c=0; ObjectSpace.each_object(Array){|e| c+=1 if e.empty? }

另一个有趣的事情是,仅存在一个Proc对象.这表明to_proc仅被调用一次. (如果我第二次用符号调用map,可能会创建另一个.)

Another interesting thing is that only one Proc object exists. This suggests that to_proc is only called once. (Maybe another one would get created if I called map with a symbol a second time.)

如果将map调用更改为使用块,则不会创建这些数组.这也可以解释为什么安德鲁·格林(Andrew Grimm)的缓存对基准没有帮助.为什么要创建这些数组?

If I change the map call to use a block, these arrays are not created. This also might explain why Andrew Grimm's caching didn't help the benchmarks. Why are these arrays being created?

更新

显然,从Symbol创建的proc每次调用时都会创建一个空数组.

Apparently a proc created from a Symbol creates an empty array every time it's called.

如果我将上面的map行替换为

If I replace the map line above with

pr=:to_i.to_proc; r.map(&pr)

导致要创建数组,但这

pr=proc{|e|e.to_i}; r.map(&pr)

没有.如果我只是执行pr.call(value),也会发生类似的事情.

does not. Similar thing happens if I just do pr.call(value).

(什么时候是proc而不是proc?)

(When is a proc not a proc?)

推荐答案

我想我找到了答案.

我查看了activesupport 2.2,并将其作为Symbol#to_proc的正文:

I looked at activesupport 2.2 and found this as the body of Symbol#to_proc:

Proc.new { |*args| args.shift.__send__(self, *args) }

args是数组.由于范围的每个成员都作为单个arg传递,因此它将转换为1个元素的数组.那一个元素被移开,留下一个空数组.因此,它不是创建空数组,而是在处理了args之后将它们留在了后面.

args is the array. Since each member of the range is passed as a single arg, it gets converted to an array of 1 element. That one element is shifted off, leaving an empty array. So it's not creating empty arrays, it's just leaving them behind after processing the args.

我还使用2-arg proc进行了测试:

I've also done a test using a 2-arg proc:

[1,2,3,4].inject(&:+)

这将留下1个元素的数组(原始的第一个元素是当前总和).

This leaves behind arrays of 1 element (the original first element is the current sum).

我的假设是1.8.7做类似的事情.我很想知道1.9有什么不同.

My assumption is that 1.8.7 does something similar. I'm curious to know how 1.9 does it differently.

这篇关于ruby 1.8.7 to_proc创建空数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆