红宝石1.8.7 to_proc创建空数组(ruby 1.8.7 to_proc creates e

2019-09-20 17:04发布

这是一个后续这个答案 ,对于红宝石1.8.7的符号#to_proc生成新的进程内每次调用。

似乎有更回事不是答案建议。

下面是一些示例代码:

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

这表明正在创造大约有一千阵列。 这表明,大约有一千都是空的:

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

另一个有趣的事情是,只有一个PROC对象存在。 这表明, to_proc只调用一次。 (也许另外一个会得到创建,如果我叫map与符号第二次。)

如果我改变地图调用使用块,不创建这些阵列。 这也可以解释为什么安德鲁·格林缓存没有帮助的基准。 为什么要创建这些阵列?

UPDATE

显然,从符号创建一个进程创建每次被称为时间空数组。

如果我更换了map线以上

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

导致创建阵列,但这种

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

才不是。 类似的事情发生,如果只是我pr.call(值)。

(当一个进程不是PROC?)

Answer 1:

我想我找到了答案。

我看着的ActiveSupport 2.2,发现这是身体Symbol#to_proc

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

args是数组。 由于该范围的每个成员被作为一个单一的传递ARG,它被转换为1个元素的阵列。 一个元件被移位,留下一个空数组。 所以它不是建立空数组,其处理后ARGS刚刚离开他们后面。

我也做使用2 ARG PROC测试:

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

此留下1个元件的阵列(原始第一元件是当前总和)。

我的假设是,1.8.7做类似的事情。 我很好奇,想知道1.9是怎么做的不同。



文章来源: ruby 1.8.7 to_proc creates empty arrays