6

次の Ruby コードがあるとします。

class Blah
  def self.bleh
    @blih = "Hello"
    @@bloh = "World"
  end
end

@blih と @@bloh とは正確には何ですか? @blih は Blah クラスのインスタンス変数で、@@bloh は Blah クラスのクラス変数ですね。@@bloh は Blah のクラスである Class の変数ということですか?

4

4 に答える 4

5

メソッドがクラスメソッドであることを人々は無視しているようです。

@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"
于 2010-04-08T11:38:00.407 に答える
4

この狂気への方法があります...

class Example
  @foo # class instance variable
  @@bar # class variable

  def fun1
    @baz # instance variable
  end
end

インスタンス変数

インスタンス変数(@fooおよび@baz例では)は常にで始まり@、クラスのオブジェクトまたはクラスを表すClassオブジェクトのいずれかである自分自身が参照するオブジェクトに常に属します。クラス定義またはクラスメソッドのインスタンス変数参照は、インスタンスメソッドのインスタンス変数参照とは完全に異なります。

継承
インスタンス変数はクラスによって定義されていないため、継承メカニズムとは無関係です。インスタンス変数は、値が割り当てられたときに作成されるだけです。したがって、クラスを表すClassオブジェクトの単なるインスタンス変数であるクラスインスタンス変数は継承されません。

クラス変数

クラス変数は、クラスのクラスメソッドとインスタンスメソッド、およびクラス定義自体に表示され、共有されます。クラス変数は、インスタンスメソッド、クラスメソッド、およびクラス定義自体で、任意のメソッドの外部で使用できます。クラス変数は、それを囲むクラス定義ステートメントによって作成されたクラスオブジェクトを参照して常に評価されます

クラスインスタンス変数とインスタンス変数

クラスインスタンス変数の欠点は、クラス変数のようにインスタンスメソッド内で使用できないことです。もう1つの欠点は、それらを通常のインスタンス変数と混同する可能性があることです。クラス変数に対するクラスインスタンス変数の利点は、既存のクラスをサブクラス化するときのクラス変数の紛らわしい動作と関係があります。クラスがクラス変数を使用する場合、どのサブクラスも値を変更することでクラスとそのすべての子孫の動作を変更できます。共有クラス変数の。これは、クラス変数の代わりにクラスインスタンス変数を使用するための強力な議論です。

これの多くは、優れた「Rubyプログラミング言語」からのものです。
代替テキスト

于 2010-04-08T11:25:05.467 に答える
1

先頭に 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

リンクテキストからの例

于 2010-04-08T09:41:37.087 に答える
0

[明確にするために編集]

クラスメソッド内にはインスタンス変数をバインドするインスタンスがないため、設定例 @blih はクラスメソッドのスコープ外には表示されません。

用語について言えば、「@@bloh はクラス Blah のクラス変数です」と言いますが、「Blah のクラス Class の変数」ではありません。クラス「クラス」はそのままです。

于 2010-04-08T10:21:29.597 に答える