Ruby @@ variable vs self.variable

时间:2018-04-04 11:08:41

标签: ruby self

在Ruby中,@@variableself.variable

之间有什么区别
  1. 在main。

  2. 的范围内
  3. 在班级

  4. 的范围内
  5. 在方法范围内

  6. 例如我的文件如下:

    self.variable = 'data'
    @@variable = 'data'
    
    def class A
      self.variable = 'data'
      @@variable = 'data'
    
      def method()
        self.variable = 'data'
        @@variable = 'data'
      end
    end
    

    有多少变量?在什么范围内?

2 个答案:

答案 0 :(得分:3)

self.variable = 'data'

这是toplevel的方法调用。 self.只是将它区分为方法调用与局部变量定义。假设你在某处有def variable= x,它会调用该方法。否则它是NoMethodError

@@variable = 'data'

这会生成一个警告:“来自toplevel的类变量访问”。类变量在该类子类的所有对象之间共享。 Toplevel的类只是Object,所以实际上这是一个全局类变量[].instance_eval { @@variable } # 'data',因为所有内容最终都来自Object。

def class A
  self.variable = 'data'
  @@variable = 'data'

与上述相同,但现在接收方为A,因此它会调用A.variable=('data')并在@@variable上设置A

  def method()
    self.variable = 'data'
    @@variable = 'data'

现在接收器是A的一些实例,让我们说a = A.new。所以它是a.variable=('data')。像@@variable一样设置A,因为类的所有实例(及其子类)共享一个变量。

的情况下,如果您在班级的上下文中看到self.variable = 'data'attr_accessor :variable,则可以认为attr_writer :variable意味着什么。在这些情况下,它是设置@variable的特定方法调用。否则它可以做任何事情,你需要阅读方法定义。

答案 1 :(得分:0)

  1. @@variable范围内self.variablemain之间的差异。
  2. 我们可能知道,@@variable是一个类变量。

    @@variable会将自己附加到self.class的班级。主要类是Object

    演示:

    self # => main
    self.class # => Object
    @@variable = "variable"
    self.class.class_variables # => [:@@variable]
    object.class_variables # => [:@@variable]
    

    请注意,这意味着每个对象都可以访问@@variable

    String.class_variables # => [:@@variable]
    

    并在顶层修改该变量也会改变所有对象的值。

    self.variable将提供NoMethodError,因为它没有吸气剂或制定者。如果你要定义一个getter和setter,那么......

    class Object
      class << self
        attr_accessor :variable
      end
    end
    self.variable = "variable" # => "variable"
    
    1. 班级范围内@@variableself.variable之间的差异。
    2. @@variable将采用与上述相同的方式,除了现在而不是类Object,我们将其应用于我们当前所在的任何课程。

      但现在,self.variable将应用于类实例变量。这是一种变量,在其他语言中最常被称为类变量或静态变量(即,只能访问该类,而不能访问其子类)。这与在班级最高级别@variable相同。

      class T
        @some = "some"
        class << self
          attr_accessor :variable
        end
        self.variable = "variable"
      end
      T.instance_variables # => [:@some, :@variable]
      
      1. 方法范围内@@variableself.variable之间的差异。
      2. @@variable的行为如上所述 - 它仍然指的是我们定义方法的类。

        但现在self.variable指的是实例变量,而不是Class的实例。

        class T
          attr_accessor :variable
          def initialize
            self.variable = "variable"
          end
        end
        instance = T.new
        instance.instance_variables
        instance.variable # => "variable"
        
        1. &#34;有多少变量?在什么范围内?&#34;
        2. 在您的示例中,有5个变量(假设已创建正确的getter / setter):

          1. 属于@@variable
          2. 的类变量Object
          3. 属于main.variable类实例main的实例变量Object
          4. 属于@@variable
          5. 的类变量A
          6. 属于班级A.variable
          7. 的班级实例变量A
          8. 属于@variable
          9. 的任何实例的实例变量A