Inconsistent behavior of singleton methods that access class variables: 1.8.7 vs 1.9.2

Sample code (based on fragment from
rails/actionpack/test/abstract_unit.rb):

module A
class Sample; end
module Incorrect; end
module Correct; end

class << Sample; def list; @@list ||= []; end; end
class << Incorrect; def list; @@list ||= []; end; end # original
pattern
module Correct; def self.list; @@list ||= []; end; end
end

def test_m(obj)
2.times do |i|
l = obj.list
l << “test”
printf “%d) %s %d %s\n”, i, obj.name, l.object_id, l.inspect
end
end

[A::Incorrect, A::Correct, A::Sample].each {|mod| test_m(mod) }

Output:

ruby 1.8.7 (2009-09-11 patchlevel 202) [i686-linux]:
0) A::Incorrect -603619398 [“test”]

  1. A::Incorrect -603619398 [“test”, “test”]
  2. A::Correct -603619548 [“test”]
  3. A::Correct -603619548 [“test”, “test”]
  4. A::Sample -603619398 [“test”, “test”, “test”]
  5. A::Sample -603619398 [“test”, “test”, “test”, “test”]

ruby 1.9.2dev (2009-09-28 trunk 25126) [i686-linux]:
0) A::Incorrect 79250400 [“test”]

  1. A::Incorrect 79250300 [“test”]
  2. A::Correct 79250220 [“test”]
  3. A::Correct 79250220 [“test”, “test”]
  4. A::Sample 79250060 [“test”]
  5. A::Sample 79249980 [“test”]

So, the question is, what is the correct way to declare and use such
constructs, and what caused the problem – bug in ruby or incorrect
use of class variables?

Hi,

In message “Re: Inconsistent behavior of singleton methods that access
class variables: 1.8.7 vs 1.9.2”
on Mon, 28 Sep 2009 04:06:42 +0900, Nikolai L.
[email protected] writes:

|So, the question is, what is the correct way to declare and use such
|constructs, and what caused the problem – bug in ruby or incorrect
|use of class variables?

The basic rules for class variables are:

(1) initialize at class variables at the top of the scope (in this
case, A).

(2) avoid name conflict of class variables in the same top-level
scope; in the case of the example, you used @@list several times
in the scope of A.

(3) and lastly, and most importantly, do not use class variables,
unless you really really need them; they are fundamentally global
variables.

You’ve violated all of above rules.

          matz.