【问题标题】:What's the difference between defining class instance variable in a class and a method. Why?在类和方法中定义类实例变量有什么区别。为什么?
【发布时间】:2012-06-23 06:22:24
【问题描述】:

嗯,如题所示,下面这两个类实例变量有什么区别

class Document
  @default_font = :Arial
  ...
end

class Document
  def foo
    @default_font = :Arial
  end
  ...
end

有没有人可以给我解释一下。非常感谢。

【问题讨论】:

    标签: ruby variables instance-variables class-instance-variables


    【解决方案1】:

    第二种情况不是类实例变量。这是一个普通的旧实例变量。

    【讨论】:

    • 那么它们有什么区别呢?
    【解决方案2】:

    在您的第一种情况下,该变量既不是类变量(应该以@@ 开头,也不是实例变量。它只是一个局部变量,在当前范围之外不可用,甚至在实例方法中也不可用。

    第二个是实例变量。

    class Document
      attr_accessor :var1, :var2
      @var1 = 1
      puts @var1 + 2
    
      def initialize
        @var2 = 4
        puts @var2**2
        #puts @var1 + 6
      end
    
    end
    
    1.9.2p0 :208 > class Document
    1.9.2p0 :209?>     attr_accessor :var1, :var2
    1.9.2p0 :210?>     @var1 = 1
    1.9.2p0 :211?>     puts @var1 + 2
    1.9.2p0 :212?>   
    1.9.2p0 :213 >       def initialize
    1.9.2p0 :214?>         @var2 = 4
    1.9.2p0 :215?>         puts @var2**2
    1.9.2p0 :216?>         #puts @var1 + 6
    1.9.2p0 :217 >         end
    1.9.2p0 :218?>   
    1.9.2p0 :219 >     end
    3
     => nil 
    1.9.2p0 :220 > d = Document.new
    16
     => #<Document:0x1a2f0c @var2=4> 
    

    实例方法内的@var1 + 6报错。

    【讨论】:

      【解决方案3】:

      我没有看到原始帖子的最终答案。我最近读了 Russ Olsen 的《Eloquent Ruby》一书,所以决定在这里补充一下。

      第一个例子定义单@变量的作用域是一个类作用域,也就是说,如果关键字 self 出现在方法 def 之外但仍在类定义中,它将引用对象 Document,而后者又是 Class 类的一个实例。

      因此第一个例子定义了一个类实例变量,即变量@default_font是一个类对象Document的实例变量。

      只能通过类级别的访问器方法访问该类实例变量,例如 Document.default_font,而不是 an_instance_of_Document.default_font

      所以如果你定义 attr_accessors:

      class Document
        @default_font = :Arial # this is a class instance variable, 
      
      #  def self.default_font
      #    @default_font
      #  end
      #
      #  def self.default_font=(font)
      #    @default_font = font
      #  end
      
        # or replace the above two class methods with the following
      
        class << self
          attr_accessor :default_font
        end
      end
      

      这是一些 irb 输出:

      1.9.3p429 :002 > require './document.rb'
       => true 
      1.9.3p429 :004 > Document.default_font
       => :Arial 
      1.9.3p429 :005 > Document.default_font = :Times
       => :Times 
      1.9.3p429 :006 > Document.default_font 
       => :Times 
      1.9.3p429 :007 > doc = Document.new
       => #<Document:0x007fe6730d8228> 
      1.9.3p429 :008 > doc.default_font
      NoMethodError: undefined method `default_font' for #<Document:0x007fe6730d8228>
      

      原帖中的第二个例子在def方法之外没有包含单@变量定义,说明这里的@default_font是一个实例变量,只能被类Document的实例化对象引用.

      class Document
        def default_font=(font)
          @default_font = font # this defines and set an instance variable
        end
      
        def default_font
          @default_font        # this defines an instance variable
        end
      
        # or above two defs can be replaced by the following
        attr_accessor :default_font  # this defines the instance variable and access methods
      end
      

      这是一些 irb 输出:

      1.9.3p429 :001 > require './document.rb'
       => true 
      1.9.3p429 :002 > Document.default_font
      NoMethodError: undefined method `default_font' for Document:Class
      1.9.3p429 :003 > doc = Document.new
       => #<Document:0x007ffbf1136f88> 
      1.9.3p429 :004 > doc.default_font
       => nil 
      1.9.3p429 :005 > doc.default_font = :Arial
       => :Arial 
      1.9.3p429 :006 > doc.default_font
       => :Arial 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-11-06
        • 1970-01-01
        • 2015-04-18
        • 2012-12-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多