# Can someone explain this?

**URL:** <https://www.ruby-forum.com/t/can-someone-explain-this/204476>\
**Category:** Ruby\
**Created:** [March 13, 2011, 9:10pm UTC](https://www.ruby-forum.com/t/can-someone-explain-this/204476 "2011-03-13T21:10:17Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![luislavena](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/0ea827/32.png) [@luislavena](https://www.ruby-forum.com/u/luislavena)\
**Post date:** [March 13, 2011, 9:10pm UTC](https://www.ruby-forum.com/t/can-someone-explain-this/204476/1 "2011-03-13T21:10:17Z")

</div>

# First I create a proc:

p = proc {  
self::X = Class.new  
def self.X  
X.new  
end  
}

# Then I create a module:

A = Module.new(&p)  
puts A.X # =\> #\<A:❌0x9c2e774\>

# Then i create another module:

B = Module.new(&p)  
puts B.X # =\> #\<B:❌0x9c39304\>

# Everything seems to be ok.

# And now to the strange part.

# After module B was created A.X started to return instances of B::X

puts A.X # =\> #\<B:❌0x9c38238\>

If more modules are created with the same proc method X returns  
instances of X from the last created module. If I use “self::X.new”  
instead of “X.new” everything works as expected, but I can’t understand  
why it works like that with “X.new”. Is this a bug or it’s supposed to  
be this way?

---

<div class="post-metadata">

**Author:** ![chilaquil](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/fbc32d/32.png) [@chilaquil](https://www.ruby-forum.com/u/chilaquil)\
**Post date:** [March 13, 2011, 10:13pm UTC](https://www.ruby-forum.com/t/can-someone-explain-this/204476/2 "2011-03-13T22:13:59Z")

</div>

On Mar 13, 2011, at 13:10 , Andy B. wrote:

> puts A.X # =\> #\<A:❌0x9c2e774\>
> 
> If more modules are created with the same proc method X returns  
> instances of X from the last created module. If I use “self::X.new”  
> instead of “X.new” everything works as expected, but I can’t understand  
> why it works like that with “X.new”. Is this a bug or it’s supposed to  
> be this way?

I suggest you send that to ruby-core@

---

<div class="post-metadata">

**Author:** ![chilaquil](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/fbc32d/32.png) [@chilaquil](https://www.ruby-forum.com/u/chilaquil)\
**Post date:** [March 14, 2011, 1:01am UTC](https://www.ruby-forum.com/t/can-someone-explain-this/204476/3 "2011-03-14T01:01:30Z")

</div>

[+ruby-core]

Also note that calling A.module\_eval(&p) after your code then changes  
both methods to create A instances.

In Ruby 1.9, there is an inline cache for constant references. Dumping  
the bytecode for the self.X method  
shows this in action:

[3,  
[:trace, 8],  
4,  
[:trace, 1],  
[:getinlinecache, :label\_11, 0],  
[:getconstant, :X],  
[:setinlinecache, 0],  
:label\_11,  
[:send, :new, 0, nil, 0, 1],  
5,  
[:trace, 16],  
4,  
[:leave]]

If you use self::X.new in A/B.X, this forces constant resolution each  
time, and the inline cache is not used:

[3,  
[:trace, 8],  
4,  
[:trace, 1],  
[:putself],  
[:getconstant, :X],  
[:send, :new, 0, nil, 0, 1],  
5,  
[:trace, 16],  
4,  
[:leave]]

The proc is compiled only once, and thus so does the method definition.  
The two method objects  
are in fact distinct, of course.

> > A.method(:X) == B.method(:X)  
> > =\> false

My best guess: the two methods likely share the same instruction  
sequence object, and thus the  
same inline caches, and the cache is not properly clearing when it  
should be.

Michael E.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
[http://carboni.ca/](http://carboni.ca/)
