Ruby: Unexpected Exec Class Results When Defining a Class Variable

In Ruby, by defining the contents of class c class_exec, I get unexpected results. When I define a class variable in a block sent to class_exec, the class variable is defined on Objectinstead of the class it is being called on class_exec:

class X; end
X.class_exec do
  @@inner_value = "123"
  def inner_value
    @@inner_value
  end
  def inner_value=(arg)
    @@inner_value = arg
  end
end

obj1 = X.new
puts obj1.inner_value
puts @@inner_value
puts Object.class_variables

It produces:

123
123
@@inner_value

This does not happen when using class_eval:

X.class_eval(<<-RUBY)
  @@inner_value = "123"
  def inner_value
    @@inner_value
  end
  def inner_value=(arg)
    @@inner_value = arg
  end
RUBY

obj1 = X.new
puts obj1.inner_value
puts @@inner_value
puts Object.class_variables

It produces:

123

and error:

uninitialized class variable @@inner_value in Object (NameError)

The results with class_eval are what I would expect in both cases. I tried this with MRI 1.8.7 and MRI 1.9.3 and got the same results as in Windows XP.

Is this the expected behavior? If so, why? If not, is it a mistake?

+2
source share
1 answer

, . , class_exec, , class_exec, Object.

, _exec , Object, , . :

public

class Object
    @@x = "ribbit"
end

def foo
    puts "test: #{@@x}"
end

x = Object.new
x.foo

, vars , , ( ), . . :

class WithClassVars
    def self.classvars
        @classvars ||= {}
    end

    def classvars
        self.class.classvars
    end
end

class A < WithClassVars;end
class B < WithClassVars;end

a = A.new
b = B.new
a.classvars[:a] = 1
b.classvars[:a] = 2

puts a.classvars
puts b.classvars

a b .

class_eval, class_eval, , .

, , class_eval, - . :

class WithClassVars
    def self.classvars
        @classvars ||= {}
    end

    def classvars
        self.class.classvars
    end
end

class A < WithClassVars;end
class B < WithClassVars;end

a = A.new
b = B.new
a.classvars[:a] = 1
b.classvars[:a] = 2

puts a.classvars
puts b.classvars
+2

All Articles