ruby 1.8.7 to_proc创建空数组
这是对这个答案的后续,关于ruby 1.8.7的Symbol#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
这表明正在创建大约一千个arrays。 这表明大约有一千个是空的:
c=0; ObjectSpace.each_object(Array){|e| c+=1 if e.empty? }
另一个有趣的事情是只存在一个Proc对象。 这表明to_proc
只被调用一次。 (如果我第二次用符号调用map
,可能会创建另一个。)
如果我将地图调用更改为使用块,则不会创建这些数组。 这也可以解释为什么Andrew Grimm的缓存对基准没有帮助。 为什么要创建这些数组?
UPDATE
显然,从Symbol创建的proc每次调用时都会创建一个空数组。
如果我用上面的map
线替换
pr=:to_i.to_proc; r.map(&pr)
导致创建数组,但这
pr=proc{|e|e.to_i}; r.map(&pr)
才不是。 如果我只是做pr.call(值),会发生类似的事情。
(什么时候proc不是proc?)
我想我找到了答案。
我查看了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的不同之处。
- Rails – ruby / 2.1.0 / minitest / parallel_each.rb:67:in”:类’Minitest :: Unit’的未定义方法’_run_suites’(NameError)
- ActiveAdmin:按子对象的计数进行筛选
- 使用Open :: URI显示HTTP标头?
- 如果没有在Rails 3中重新加载,数据库值不会出现在同一页面中
- 使用带有序列化自定义类的Rails表单助手
- ! 主 – >主(预接收挂钩拒绝)
- 在尝试保存大(ish)整数值时,获取指示编号的错误“超出ActiveRecord :: Type :: Integer且限制为4”的范围
- Ruby:文件行的长度(以字节为单位)?
- Ruby on Rails和来自URL的JSON解析器