From: Marc-Andre Lafortune <ruby-core@...>
Date: 2012-02-17T04:26:44+09:00
Subject: [ruby-core:42694] [ruby-trunk - Bug #6038] #instance_eval bug


Issue #6038 has been updated by Marc-Andre Lafortune.


Might be a good idea to keep things simple:

    do_stuff = lambda do |&block|
      puts "Object id is #{block.object_id}"
    end

    chain = lambda{}

    do_stuff.call(&chain)
    chain.instance_eval{}
    do_stuff.call(&chain)

Prints out:
Block's object id is 2152284220
Block's object id is 2152284140

Using an equivalent method to `do_stuff` doesn't exhibit the same problem. Here's a complete example:

    def stuff(&block)
      puts "Object id is #{block.object_id}"
    end
    do_stuff = method(:stuff).to_proc  

    chain = lambda{}

    stuff(&chain)
    do_stuff.call(&chain)
    chain.instance_eval{}
    stuff(&chain)
    do_stuff.call(&chain)

Object id is 2156158200
Object id is 2156158200
Object id is 2156158200
Object id is 2156157980

----------------------------------------
Bug #6038: #instance_eval bug
https://bugs.ruby-lang.org/issues/6038

Author: Denis de Bernardy
Status: Open
Priority: Normal
Assignee: 
Category: 
Target version: 
ruby -v: 1.9.3


instance_eval seems to change the object_id in some cases:


begin
  stack = []
  do_stuff = lambda do |&chain|
    puts "Actual: #{chain.object_id}"
    chain.call
  end

  chain = lambda do
    if filter = stack.shift
      filter.call(&chain)
    end
  end

  puts "Expected: #{chain.object_id}"
  stack << do_stuff
  chain.instance_eval { @completed = false }
  chain.call
end

>> RUBY_VERSION
=> "1.9.3"
>> begin
?>   stack = []
>>   do_stuff = lambda do |&chain|
?>     puts "Actual: #{chain.object_id}"
>>     chain.call
>>   end
>> 
?>   chain = lambda do
?>     if filter = stack.shift
>>       filter.call(&chain)
>>     end
>>   end
>> 
?>   puts "Expected: #{chain.object_id}"
>>   stack << do_stuff
>>   chain.instance_eval { @completed = false }
>>   chain.call
>> end
Expected: 2152379740
Actual: 2152379520



-- 
http://bugs.ruby-lang.org/