Каква е разликата между дефиниране на променлива на екземпляр на клас в клас и метод. Защо?

Е, като показаното заглавие, каква е разликата между двете променливи на екземпляр на класа по-долу

class Document
  @default_font = :Arial
  ...
end

И

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

Има ли някой да ми обясни. Благодаря ти много.


person Alex Locanda    schedule 21.06.2012    source източник


Отговори (3)


В първия ви случай променливата не е нито променлива на клас (която трябва да започва с @@, нито променлива на екземпляр. Това е просто локална променлива, която не е налична извън текущия обхват, нито дори в методите на екземпляра.

Втората е променлива на екземпляр.

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 вътре в метода на екземпляр дава грешка.

person Anil    schedule 21.06.2012

Вторият сценарий не е променлива на екземпляр на клас. Това е обикновена стара променлива на екземпляр.

person Andrew Grimm    schedule 21.06.2012
comment
И така, каква е разликата между тях? - person Alex Locanda; 21.06.2012

Не видях окончателен отговор на оригиналния пост. Наскоро прочетох книгата „Красноречивият Руби“ от Ръс Олсен, така че реших да добавя моята информация за вкъщи тук.

Обхватът, в който първият пример дефинира променливата single-@, е клас-обхват, т.е. ако ключовата дума self трябваше да се появи извън дефиниран метод, но все още в дефиницията на класа, тя ще препраща към обект Документ, който от своя страна е екземпляр на класа 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 
person wr200m    schedule 08.08.2013