Project

General

Profile

Actions

Bug #15877

closed

Incorrect constant lookup result in method on cloned class

Bug #15877: Incorrect constant lookup result in method on cloned class

Added by danielwaterworth (Daniel Waterworth) over 6 years ago. Updated over 6 years ago.

Status:
Closed
Target version:
-
[ruby-core:92849]

Description

This behavior seems wrong to me:

class Foo def test TEST end end Bar1 = Foo.clone Bar2 = Foo.clone class Bar1 TEST = 'bar-1' end class Bar2 TEST = 'bar-2' end # If these two lines are reordered, 'bar-2' is produced each time p [:bar1_method, Bar1.new.test] # outputs 'bar-1' (correct) p [:bar2_method, Bar2.new.test] # outputs 'bar-1' (incorrect) p [:bar1_const, Bar1::TEST] # outputs 'bar-1' (correct) p [:bar2_const, Bar2::TEST] # outputs 'bar-2' (correct) 

Possibly related to #9603, #7107

Updated by danielwaterworth (Daniel Waterworth) over 6 years ago Actions #1 [ruby-core:92850]

Running with RubyVM::InstructionSequence.compile_option = {inline_const_cache: false} produces the correct result.

Updated by danielwaterworth (Daniel Waterworth) over 6 years ago Actions #2

  • Description updated (diff)

Updated by sag (Stephen Gregory) over 6 years ago Actions #3 [ruby-core:92867]

I tested this on 2.5, 2.4 and the behavior is the same there. Also this applies to subclasses as well. The first class READ determines the values for all of them.

class Unrelated TEST='UNRELATED' def test TEST end end class Foo def test TEST end end Bar2 = Foo.clone Bar1 = Foo.clone class Bar1 TEST = 'bar-1' end class Bar2 TEST = 'bar-2' end class Bar3 < Foo TEST = 'bar-3' end puts "Bar2 #{Bar2.new.test}" # Bar2 bar-2 puts "Bar1 #{Bar1.new.test}" # Bar1 bar-2 puts "Bar3 #{Bar3.new.test}" # Bar3 bar-2 puts "Foo #{Foo.new.test}" # Foo bar-2 puts "Unrelated #{Unrelated.new.test}" #Unrelated UNRELATED 

Interestingly if Bar3 is read first then you get:

sample/array_second.rb:12:in `test': uninitialized constant Foo::TEST (NameError)	from sample/array_second.rb:30:in `<main>' 

Updated by ko1 (Koichi Sasada) over 6 years ago Actions #4 [ruby-core:93973]

  • Status changed from Open to Assigned
  • Assignee set to ko1 (Koichi Sasada)

oops!

Updated by ko1 (Koichi Sasada) over 6 years ago Actions #5

  • Status changed from Assigned to Closed

Applied in changeset git|b004d3e8300ba803d4a499148fa4fc6a690149e6.


solve "duplicate :raise event" [Bug #15877]

Without this patch, "raise" event invoked twice when raise an
exception in "load"ed script.
This patch by danielwaterworth (Daniel Waterworth).
[Bug #15877]

Updated by nagachika (Tomoyuki Chikanaga) over 6 years ago Actions #6 [ruby-core:94197]

  • Status changed from Closed to Assigned
  • Backport changed from 2.4: UNKNOWN, 2.5: UNKNOWN, 2.6: UNKNOWN to 2.4: UNKNOWN, 2.5: UNKNOWN, 2.6: REQUIRED

Re-open. This ticket has been closed accidentally by b004d3e8.
I'll correct commit link.

Updated by nobu (Nobuyoshi Nakada) over 6 years ago Actions #7

  • Status changed from Assigned to Closed

Applied in changeset git|76bd0714cf1140ffd64bf564446c76c54f2c4870.


solve "duplicate :raise event" in require too [Bug #15877]

Updated by nobu (Nobuyoshi Nakada) over 6 years ago Actions #8 [ruby-core:94199]

  • Status changed from Closed to Open

I copied the wrong commit log, sorry.

Updated by ko1 (Koichi Sasada) over 6 years ago Actions #9

  • Status changed from Open to Closed

Applied in changeset git|71efad1ed391ee0c5398a76306fdbaaadd4dc52e.


introduce RCLASS_CLONED flag for inline cache.

Methods on duplicated class/module refer same constant inline
cache (IC). Constant access lookup should be done for cloned
class/modules but inline cache doesn't check it.
To check it, this patch introduce new RCLASS_CLONED flag which
are set when if class/module is cloned (both orig and dst).
[Bug #15877]

Updated by ko1 (Koichi Sasada) over 6 years ago Actions #10 [ruby-core:94211]

solve "duplicate :raise event" [Bug #15877]

sorry my mistake :p

Actions

Also available in: PDF Atom