为什么使用class_eval会导致设置顶级类变量?

时间:2018-02-14 17:06:23

标签: ruby class oop

我写了一些代码来了解class_eval方法。我的理解是Foo.class_eval会将self设置为“Foo”并在该上下文中评估下面的块,就像说“class Foo”一样。但是,下面的代码显示使用class_eval设置类变量会将顶级的类变量赋值为“Object”。为什么会这样?

class Foo
end

class Foo
  puts self
  # => Foo
  @@class_var = "hello"
end

puts Object.class_variables
# => []

Foo.class_eval do
    puts self
    # => Foo
    @@class_var = "hi"
    # => warning: class variable access from toplevel
end

puts Object.class_variables
# => @@class_var

1 个答案:

答案 0 :(得分:0)

正如评论中指出的那样,单个@会做你想要的,现在如果你从另一个类@@内部运行代码可以工作,但它会为两个Foo设置一个类变量,无论你从哪个班级开始:

class Foo
  puts self
  # => Foo
  @@class_var = "hello"
end

class Bar
  def self.main
    puts Object.class_variables
    # => []

    Foo.class_eval do
      puts self
      # => Foo
      @@class_var = "hi"
    end
  end
end

Bar.main
p [Bar.class_variables]
#[[:@@class_var]]
p [Foo.class_variables]
#[[:@@class_var]]

这与procblock范围有关,我希望它仅在@@class_var类上设置Bar,但它实际上设置在两者上,很奇怪。