クラス変数とクラスインスタンス変数の違いについて誰か教えてもらえますか?
回答:
クラス変数(@@
)は、クラスとそのすべての子孫の間で共有されます。クラスインスタンス変数(@
)は、クラスの子孫によって共有されません。
クラス変数(@@
)
クラス変数を持つクラスFooと、@@i
読み書き用のアクセサを作ってみましょう@@i
:
class Foo
@@i = 1
def self.i
@@i
end
def self.i=(value)
@@i = value
end
end
そして派生クラス:
class Bar < Foo
end
FooとBarの値が同じであることがわかります@@i
。
p Foo.i # => 1
p Bar.i # => 1
そして@@i
、一方を変更すると、両方で変更されます。
Bar.i = 2
p Foo.i # => 2
p Bar.i # => 2
クラスインスタンス変数(@
)
@i
読み書き用のクラスインスタンス変数とアクセサーを使用して、単純なクラスを作成してみましょう@i
。
class Foo
@i = 1
def self.i
@i
end
def self.i=(value)
@i = value
end
end
そして派生クラス:
class Bar < Foo
end
Barはのアクセサを継承しますが@i
、それ@i
自体は継承しません。
p Foo.i # => 1
p Bar.i # => nil
@i
Fooに影響を与えずにBarを設定できます@i
。
Bar.i = 2
p Foo.i # => 1
p Bar.i # => 2
最初に、クラスもインスタンスであることを理解する必要があります- Class
クラスのインスタンス。
これを理解すると、通常の(読み取り:非クラス)オブジェクトと同じように、クラスにインスタンス変数を関連付けることができることを理解できます。
Hello = Class.new
# setting an instance variable on the Hello class
Hello.instance_variable_set(:@var, "good morning!")
# getting an instance variable on the Hello class
Hello.instance_variable_get(:@var) #=> "good morning!"
上でインスタンス変数ことに注意してくださいHello
にインスタンス変数とは完全に無関係と区別されるインスタンスのHello
hello = Hello.new
# setting an instance variable on an instance of Hello
hello.instance_variable_set(:@var, :"bad evening!")
# getting an instance variable on an instance of Hello
hello.instance_variable_get(:@var) #=> "bad evening!")
# see that it's distinct from @var on Hello
Hello.instance_variable_get(:@var) #=> "good morning!"
クラス変数に、それがアクセス可能として一方は、上記の二つの組み合わせの一種でありHello
、それ自体とそのインスタンス、並びにのサブクラスにHello
及びそのインスタンス。
HelloChild = Class.new(Hello)
Hello.class_variable_set(:@@class_var, "strange day!")
hello = Hello.new
hello_child = HelloChild.new
Hello.class_variable_get(:@@class_var) #=> "strange day!"
HelloChild.class_variable_get(:@@class_var) #=> "strange day!"
hello.singleton_class.class_variable_get(:@@class_var) #=> "strange day!"
hello_child.singleton_class.class_variable_get(:@@class_Var) #=> "strange day!"
多くの人々はclass variables
上記の奇妙な振る舞いのために避けるように言い、class instance variables
代わりにの使用を勧めます。
また@@
、クラスのインスタンスからクラス変数()にアクセスできることを追加します
class Foo
def set_name
@@name = 'Nik'
end
def get_name
@@name
end
end
a = Foo.new
a.set_name
p a.get_name # => Nik
b = Foo.new
p b.get_name # => Nik
ただし、クラスインスタンス変数(@
)に対して同じことを行うことはできません。
class Foo
def set_name
@name = 'Nik'
end
def get_name
@name
end
end
a = Foo.new
a.set_name
p a.get_name # => Nik
b = Foo.new
p b.get_name # => nil
Foo.i
、このクラスのすべてのインスタンスに対して同じようにするにはどうすればよいFoo.new.i
ですか?
#class
。私は個人的#class
には、何かが呼び出されたときの使用法を考えself
ていますが、コードの匂いです。あなたも、さらに一歩進み、インスタンスアクセサ実装することができますi
し、i=
彼らにそのデリゲートを#class
あなたが行うことができ、その場合には同等、Foo.new.i
。混乱を招くインターフェースが作成されるため、この方法はお勧めしません。オブジェクトメンバーを変更することをお勧めします。