次の Ruby コードがあるとします。
class Blah
def self.bleh
@blih = "Hello"
@@bloh = "World"
end
end
@blih と @@bloh とは正確には何ですか? @blih は Blah クラスのインスタンス変数で、@@bloh は Blah クラスのクラス変数ですね。@@bloh は Blah のクラスである Class の変数ということですか?
次の Ruby コードがあるとします。
class Blah
def self.bleh
@blih = "Hello"
@@bloh = "World"
end
end
@blih と @@bloh とは正確には何ですか? @blih は Blah クラスのインスタンス変数で、@@bloh は Blah クラスのクラス変数ですね。@@bloh は Blah のクラスである Class の変数ということですか?
メソッドがクラスメソッドであることを人々は無視しているようです。
@blih は、定数 Bleh のクラス Class のインスタンスのインスタンス変数になります。したがって:
irb(main):001:0> class Bleh
irb(main):002:1> def self.bleh
irb(main):003:2> @blih = "Hello"
irb(main):004:2> @@blah = "World"
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> Bleh.instance_variables
=> []
irb(main):008:0> Bleh.bleh
=> "World"
irb(main):009:0> Bleh.instance_variables
=> ["@blih"]
irb(main):010:0> Bleh.instance_variable_get :@blih
=> "Hello"
@@blah は、Bleh のクラス変数として使用できます。
irb(main):017:0> Bleh.class_variables
=> ["@@blah"]
irb(main):018:0> Bleh.send :class_variable_get, :@@blah
=> "World"
この狂気への方法があります...
class Example
@foo # class instance variable
@@bar # class variable
def fun1
@baz # instance variable
end
end
インスタンス変数(@foo
および@baz
例では)は常にで始まり@
、クラスのオブジェクトまたはクラスを表すClassオブジェクトのいずれかである自分自身が参照するオブジェクトに常に属します。クラス定義またはクラスメソッドのインスタンス変数参照は、インスタンスメソッドのインスタンス変数参照とは完全に異なります。
継承
インスタンス変数はクラスによって定義されていないため、継承メカニズムとは無関係です。インスタンス変数は、値が割り当てられたときに作成されるだけです。したがって、クラスを表すClassオブジェクトの単なるインスタンス変数であるクラスインスタンス変数は継承されません。
クラス変数は、クラスのクラスメソッドとインスタンスメソッド、およびクラス定義自体に表示され、共有されます。クラス変数は、インスタンスメソッド、クラスメソッド、およびクラス定義自体で、任意のメソッドの外部で使用できます。クラス変数は、それを囲むクラス定義ステートメントによって作成されたクラスオブジェクトを参照して常に評価されます。
クラスインスタンス変数の欠点は、クラス変数のようにインスタンスメソッド内で使用できないことです。もう1つの欠点は、それらを通常のインスタンス変数と混同する可能性があることです。クラス変数に対するクラスインスタンス変数の利点は、既存のクラスをサブクラス化するときのクラス変数の紛らわしい動作と関係があります。クラスがクラス変数を使用する場合、どのサブクラスも値を変更することでクラスとそのすべての子孫の動作を変更できます。共有クラス変数の。これは、クラス変数の代わりにクラスインスタンス変数を使用するための強力な議論です。
これの多くは、優れた「Rubyプログラミング言語」からのものです。
先頭に 2 つのアットマークが付いた変数はクラス変数であり、クラスのインスタンス メソッドとクラス メソッドの両方でアクセスできます。
例:
class CountEm
@@children = 0
def initialize
@@children += 1
@myNumber = @@children
end
def whoAmI
"I'm child number #@myNumber (out of #@@children)"
end
def CountEm.totalChildren
@@children
end
end
c1 = CountEm.new
c2 = CountEm.new
c3 = CountEm.new
c1.whoAmI # -> "I'm child number 1 (out of 3)"
c3.whoAmI # -> "I'm child number 3 (out of 3)"
CountEm.totalChildren # -> 3
リンクテキストからの例
[明確にするために編集]
クラスメソッド内にはインスタンス変数をバインドするインスタンスがないため、設定例 @blih はクラスメソッドのスコープ外には表示されません。
用語について言えば、「@@bloh はクラス Blah のクラス変数です」と言いますが、「Blah のクラス Class の変数」ではありません。クラス「クラス」はそのままです。