[#35446] [Ruby 1.9 - Bug #4477][Open] Kernel:exec and backtick (`) don't work for certain system commands — Joachim Wuttke <j.wuttke@...>

10 messages 2011/03/07

[#35476] [Ruby 1.9 - Bug #4489][Open] [PATCH] Encodings with /-(unix|dos|mac)\Z/ — "James M. Lawrence" <quixoticsycophant@...>

20 messages 2011/03/10

[#35552] [Ruby 1.9 - Feature #4523][Open] Kernel#require to return the path of the loaded file — Alex Young <alex@...>

14 messages 2011/03/24

[#35565] [Ruby 1.9 - Feature #4531][Open] [PATCH 0/7] use poll() instead of select() in certain cases — Eric Wong <normalperson@...>

33 messages 2011/03/28

[#35566] [Ruby 1.9 - Feature #4532][Open] [PATCH] add IO#pread and IO#pwrite methods — Eric Wong <normalperson@...>

12 messages 2011/03/28

[#35586] [Ruby 1.9 - Feature #4538][Open] [PATCH (cleanup)] avoid unnecessary select() calls before doing I/O — Eric Wong <normalperson@...>

9 messages 2011/03/29

[ruby-core:35494] Re: can someone explain this?

From: Michael Edgar <adgar@...>
Date: 2011-03-13 23:55:04 UTC
List: ruby-core #35494
[+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 Edgar
adgar@carboni.ca
http://carboni.ca/

On Mar 13, 2011, at 4:10 PM, Andy Bogdanov wrote:

> # 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::X:0x9c2e774>
> 
> # Then i create another module:
> B = Module.new(&p)
> puts B.X # => #<B::X: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::X: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?
> 
> -- 
> Posted via http://www.ruby-forum.com/.
> 


In This Thread

Prev Next