【问题标题】:What can't I access class variable from object in ruby?什么不能从 ruby​​ 中的对象访问类变量?
【发布时间】:2011-08-26 06:17:13
【问题描述】:

我不想从外部(通过 attr_accessor)设置一个类的类变量,然后从它的一个对象内部访问它。我正在使用红宝石 1.9.2。这是我的代码:

class Service
  def initialize(id)
    @my_id = id   
  end

  class << self
    attr_accessor :shared_id
  end

  def system_id
    @my_id + @@shared_id
  end
end

如果我设置Service.shared_id = "A2",然后调用Service.new("A").system_id,这不会返回“AA2”。它显示以下错误:

服务中未初始化的类变量@@shared_id

这种行为就像我没有设置 Service.service_id 一样。有人能解释一下为什么会这样吗?

【问题讨论】:

    标签: ruby class-variables


    【解决方案1】:

    attr_accessor 创建操作实例变量的方法——它不创建实例或类变量。要创建类变量,您必须将其设置为:

    @@shared_id = something
    

    没有生成类变量访问器的辅助方法,所以你必须自己编写。

    然而,类变量,因为它们奇怪的查找规则,很少使用——甚至避免使用。而是使用类级别的实例变量。

    class Service
      @shared_id = thing
    
      class << self
        attr_accessor :shared_id
      end
    
      def system_id
         # use self.class.shared_id; you could add a shared_id helper to generate it, too.
      end
    end
    

    【讨论】:

    • 简而言之,类实例级别的 attr_accessor 不使用全局变量。它在该类中使用实例变量。
    【解决方案2】:

    cattr_accessor怎么样?

    【讨论】:

    • 这行得通,但我想了解为什么我的代码没有。但是,我发现您发布的链接非常有用,因为有几个 cmets 确实解释了 class_inheritable_accessor 实际上不使用全局变量。
    【解决方案3】:

    请记住,@@class_var 对所有类都是全局的。

    【讨论】:

    • 你的意思是全局的所有子类吗?如果没有,我不明白这个:S
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-15
    • 2017-07-09
    • 1970-01-01
    相关资源
    最近更新 更多