ruby - How is a proc object preserved under `&`-`&` roundtrip? -


when splat array * when passing method, reconstruct array * within method, identity of array not preserved:

a = [] a.object_id # => 69846339548760 def bar *a; a.object_id end bar(*a) # => 69846339537540 

however, when turn proc block & when passing method, reconstruct proc block & within method, identity of proc seems preserved:

pr = ->{} pr.object_id # => 69846339666160 def foo ≺ pr.object_id end foo(&pr) # => 69846339666160 

how proc object preserved? isn't lost when converted block? guaranteed behaviour?

ruby vm stackmachine. when calling function, puts arguments (including self) onto stack , calls.

how array splat works - takes array contents , puts onto stack, calls function:

> puts rubyvm::instructionsequence.compile("a = []; func *a").disasm == disasm: <rubyvm::instructionsequence:<compiled>@<compiled>>========== local table (size: 2, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1]) [ 2]           0000 trace            1                                               (   1) 0002 newarray         0 0004 setlocal_op__wc__0 2 0006 putself           0007 getlocal_op__wc__0 2 0009 splatarray       false 0011 opt_send_without_block <callinfo!mid:func, argc:1, args_splat|fcall> 0013 leave   

when passing proc block, similar thing happens, ruby not have unwrap proc, proc.

added: per rubyspec's https://github.com/ruby/spec/blob/master/core/proc/block_pass_spec.rb

def revivify; proc.new; end  "remains same object if re-vivified target method"   p = proc.new {}   p2 = revivify(&p)   p.object_id.should == p2.object_id   p.should == p2 end 

this standardized behavior, @ least should followed rubinius , jruby


Comments