# 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?
on 2011-03-13 21:10
on 2011-03-13 22:13
On Mar 13, 2011, at 13:10 , Andy Bogdanov wrote: > puts A.X # => #<A::X: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@
on 2011-03-14 01:01
[+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/
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.