ruby 1.8.7 to_proc创建空数组

ruby 1.8.7 to_proc创建空数组,ruby,ruby-1.8.7,Ruby,Ruby 1.8.7,这是关于ruby 1.8.7的符号“to proc”的后续内容,它会在每次调用时生成一个新的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; ObjectSp

这是关于ruby 1.8.7的符号“to proc”的后续内容,它会在每次调用时生成一个新的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
,可能会创建另一个。)

如果将映射调用更改为使用块,则不会创建这些数组。这也可以解释为什么Andrew Grimm的缓存对基准测试没有帮助。为什么要创建这些阵列

更新

显然,由符号创建的过程每次调用时都会创建一个空数组

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

pr=:to_i.to_proc; r.map(&pr)
导致创建阵列,但

pr=proc{|e|e.to_i}; r.map(&pr)
没有。如果我只做pr.call(value),也会发生类似的事情


(什么时候proc不是proc?

我想我找到了答案

我查看了ActiveSupport2.2,发现它是
Symbol#to_proc
的主体:

Proc.new { |*args| args.shift.__send__(self, *args) }
args
是数组。由于范围的每个成员都作为单个参数传递,因此它将转换为一个包含1个元素的数组。一个元素被移开,留下一个空数组。因此,它不是创建空数组,而是在处理arg之后将它们留在后面

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

[1,2,3,4].inject(&:+)
这将留下1个元素的数组(原始的第一个元素是当前的和)

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