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
Post a Comment