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 <mikeowens / gmail.com> 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:
>
>   <compiled>:in `<compiled>': undefined method `join' for
> #<Enumerator: [["q", "test"]]:collect> (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