I recall reading somewhere that the following two pieces of code are identical in Ruby.
# Number 1
class A
# body
end
# Number 2
A = Class.new
# body
end
However I noticed that when I try to set a class variable from a class-level method, the two syntaxes produce different results.
With the first syntax, the variable is set on the class itself as expected.
irb(main):001:0> class A
irb(main):002:1> def self.foo
irb(main):003:2> @@a = :banana
irb(main):004:2> end
irb(main):005:1> end
=> :foo
irb(main):006:0> A.class_variables
=> []
irb(main):007:0> A.foo
=> :banana
irb(main):008:0> A.class_variables
=> [:@@a]
irb(main):009:0> A.class_variable_get :@@a
=> :banana
irb(main):010:0> Class.class_variable_get :@@a
NameError: uninitialized class variable @@a in Class
from (irb):10:in `class_variable_get'
from (irb):10
from /usr/local/bin/irb:11:in `<main>'
irb(main):011:0>
With the second, the variable gets set on Class
itself!
irb(main):015:0> K = Class.new do
irb(main):016:1* def self.foo
irb(main):017:2> @@k = :banana
irb(main):018:2> end
irb(main):019:1> end
=> K
irb(main):020:0> K.class_variables
=> []
irb(main):021:0> K.foo
(irb):17: warning: class variable access from toplevel
=> :banana
irb(main):022:0> K.class_variables
=> [:@@k]
irb(main):023:0> K.class_variable_get :@@k
=> :banana
irb(main):024:0> Class.class_variable_get :@@k
=> :banana
Why does this happen?
In what I am working on, I have to generate a class dynamically, so I have no choice but to use the second syntax. As such, how do I ensure that the variable @@k
gets set on the new Class
object being defined, and not on Class
itself?