From: Mike Owens Date: 2013-03-17T01:03:10+09:00 Subject: Re: RubyVM::InstructionSequence compiling and loading Actually a better example without having to recompile Ruby is the following: #!/usr/bin/env ruby require 'fiddle' class RubyVM class InstructionSequence address = Fiddle::Handle::DEFAULT['rb_iseq_load'] func = Fiddle::Function.new( address, [Fiddle::TYPE_VOIDP] * 3, Fiddle::TYPE_VOIDP ) define_singleton_method(:load) do |data, parent = nil, opt = nil| func.call(Fiddle.dlwrap(data), parent, opt).to_value end end end source = %q{ args = {} args['q'] = 'test' args.to_a.collect {|x| "#{x[0]}=#{x[1]}" }.join('&') } orig = RubyVM::InstructionSequence.new source loaded = RubyVM::InstructionSequence.load orig.to_a orig.eval loaded.eval The last eval throws the exception. It would seem like the two instruction sequences should be equivalent. On Fri, Mar 15, 2013 at 11:53 PM, Mike Owens wrote: > I recently came across "An Amateur Smalltalk User's Observations on > Ruby Object Model and Bytecode" > (http://www.slideshare.net/kstan2/smalltalk-and-ruby-20121208-15542185). > I tried his example of enabling iseq_s_load(). I stumbled across a > simple case where the loaded compiled code does not work as the > original compiled code, specifically: > > source = %q{ > args = {} > args['q'] = 'test' > args.to_a.collect {|x| "#{x[0]}=#{x[1]}" }.join('&') > } > > orig = RubyVM::InstructionSequence.compile source > loaded = RubyVM::InstructionSequence.load ins.to_a > > orig.eval > other.eval # <- Exception > > The first eval works. The second eval throws an exception: > > :in `': undefined method `join' for > # (NoMethodError) > > The result of the first collect method is (and should be) an Array. > However the second is producing an Enumerator. > > I was wondering if anyone could explain why this is the case? > > -- > Mike > -- Mike