Bug #7107

Ruby can no longer find constants in methods in anonymous modules

Added by Eric Hodel over 2 years ago. Updated about 2 years ago.

[ruby-core:47834]
Status:Closed
Priority:Normal
Assignee:Charlie Somerville
ruby -v:ruby 2.0.0dev (2012-09-06 trunk 36915) [x86_64-darwin12.1.0] Backport:

Description

=begin
With ruby 1.9 and newer C cannot be found if m is duplicated:

module M
C = 1

def self.m
  C
end

end

puts 'named module'
M.m

puts 'anonymous module'
m = M.dup
m.m

Ruby 1.8:

$ ruby -v t.rb
ruby 1.8.7 (2012-02-08 patchlevel 358) [universal-darwin12.0]
named module
anonymous module

With Ruby 1.9:

$ ruby19 -v t.rb
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin12.2.0]
named module
anonymous module
t.rb:5:in m': uninitialized constant Module::C (NameError)
from t.rb:14:in
'

With trunk:

$ ruby19 -v t.rb 
ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin12.2.0]
named module
anonymous module
t.rb:5:in `m': uninitialized constant Module::C (NameError)
    from t.rb:14:in `<main>'

(({m::C})) works in all three versions, though.
=end

Associated revisions

Revision 38423
Added by Charlie Somerville about 2 years ago

  • class.c (rewrite_cref_stack, clone_method): rewrite a method's cref stack when cloning into a new class to allow lexical const lookup to work as expected [Bug #7107]
  • test/ruby/test_class.rb (class TestClass): related test

Revision 38423
Added by Charlie Somerville about 2 years ago

  • class.c (rewrite_cref_stack, clone_method): rewrite a method's cref stack when cloning into a new class to allow lexical const lookup to work as expected [Bug #7107]
  • test/ruby/test_class.rb (class TestClass): related test

History

#1 Updated by Eric Hodel over 2 years ago

=begin
Additionally, when the module is given a name it still can't find the constant:

module M
C = 1

def self.m
  C
end

end

puts 'named module'
M.m

puts 'anonymous module'
m = M.dup
begin
m.m
rescue NameError
p $!
end

puts 're-named module'
N = m
begin
N.m
rescue NameError
p $!
end

Ruby trunk:

$ ruby20 -v t.rb
ruby 2.0.0dev (2012-09-06 trunk 36915) [x86_64-darwin12.1.0]
named module
anonymous module
#
re-named module
#

=end

#2 Updated by Koichi Sasada over 2 years ago

  • Assignee set to Yusuke Endoh

#3 Updated by Yusuke Endoh over 2 years ago

  • Assignee changed from Yusuke Endoh to Nobuyoshi Nakada
  • Status changed from Open to Assigned

Indeed, it looks a bug. Nobu, could you investigate?

Yusuke Endoh mame@tsg.ne.jp

#4 Updated by Masaya Tarui about 2 years ago

hi,

I found strange behavior.

$ ruby -e "module M;C=1;def self.f;C end end;d=M.dup;p M.f;p d.f;class A;end;p d.f"
1
1
-e:1:in f': uninitialized constant Module::C (NameError)
from -e:1:in
'

It seems to hold the problem in InlineCache too.

#5 Updated by Masaya Tarui about 2 years ago

additional sample.
d.f referring to M::C is correct? or d::C?

$ ruby -e "module M;C=1;def self.f;C end end;d=M.dup;p M.f;p d.f;d::C=2;p M.f;p d::C;p d.f"
1
1
-e:1: warning: already initialized constant #Module:0x007ffb39f4c860::C
-e:1: warning: previous definition of C was here
1
2
1

#6 Updated by Charlie Somerville about 2 years ago

=begin

Nobu, I have found the cause of the bug - the cref_stack of methods are not fixed up to point to the new class/module when the class/module is duped.

Do you want me to commit it or attach it here for your review?

=end

#7 Updated by Charlie Somerville about 2 years ago

  • Assignee changed from Nobuyoshi Nakada to Charlie Somerville

#8 Updated by Charlie Somerville about 2 years ago

  • % Done changed from 0 to 100
  • Status changed from Assigned to Closed

This issue was solved with changeset r38423.
Eric, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


  • class.c (rewrite_cref_stack, clone_method): rewrite a method's cref stack when cloning into a new class to allow lexical const lookup to work as expected [Bug #7107]
  • test/ruby/test_class.rb (class TestClass): related test

Also available in: Atom PDF