さて、示されているタイトルのように、以下の2つのクラスインスタンス変数の違いは何ですか
class Document
@default_font = :Arial
...
end
と
class Document
def foo
@default_font = :Arial
end
...
end
誰かが私にそれを説明できる人はいますか?どうもありがとうございます。
さて、示されているタイトルのように、以下の2つのクラスインスタンス変数の違いは何ですか
class Document
@default_font = :Arial
...
end
と
class Document
def foo
@default_font = :Arial
end
...
end
誰かが私にそれを説明できる人はいますか?どうもありがとうございます。
2番目のシナリオは、クラスインスタンス変数ではありません。これは単純な古いインスタンス変数です。
最初のケースでは、変数はクラス変数(で始まるはずです@@
)でもインスタンス変数でもありません。これは、インスタンスメソッド内であっても、現在のスコープ外では使用できないローカル変数です。
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
内部でエラーが発生します。
元の投稿に対する最終的な回答は見つかりませんでした。最近、ラス・オルセンの「Eloquent Ruby」という本を読んだので、ここに持ち帰りを追加することにしました。
最初の例でsingle-@変数を定義するスコープは、クラススコープです。つまり、キーワードselfがメソッドdefの外にあるが、クラス定義内にある場合、オブジェクトDocumentを参照します。 Classクラスのインスタンス。
したがって、最初の例では、クラスインスタンス変数を定義します。つまり、変数@default_fontは、クラスオブジェクトであるオブジェクトDocumentのインスタンス変数です。
このクラスインスタンス変数には、an_instance_of_Document.default_fontではなく、クラスレベルのアクセサメソッド(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>
元の投稿の2番目の例に、メソッド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