3

クラス変数を作成することがしばしば危険で予測できない場合、なぜそれらが必要なのですか?解決策がクラスレベルのアクセサーでクラスインスタンス変数を使用することだけである場合:

class Foo
  @variable = :something

  def self.getvariable
    @variable
  end

  def self.setvariable(value)
    @variable = value
  end
end

では、なぜクラス変数が必要なのですか?

4

3 に答える 3

1

これにはいくつかの原因があります。

  1. シンタックスシュガーです。を使用して、いつでもクラス変数を取得できます(クラススコープまたはインスタンススコープにあるかどうかに関係なく)@@var。これは、クラスのインスタンス変数では機能しません。

  2. クラス変数は、このクラスのインスタンスのシングルトンクラスに対して存続します。例:

    class Test
    
      @instance_var = 0
      @@class_var = 0
    
      def self.instance_var
        @instance_var
      end
    
      def self.class_var
        @@class_var
      end
    
    end
    
    Test.instance_var #=> 0
    Test.class_var #=> 0
    Test.new.singleton_class.instance_var #=> nil
    Test.new.singleton_class.class_var #=> 0
    
于 2011-07-14T13:27:25.290 に答える
1

クラス変数は時々使用されますが、固有クラスを使用する方が頻繁に役立つことに同意します。

class Foo
  @bar = 'bar'
  class << self
    attr_accessor :bar
  end
end

puts Foo.bar         # bar
puts Foo.bar = 'baz' # baz

上記は、クラス変数ではなくFoo定数に変数を設定するため、継承しても安全です。

Foo.new.instance_eval { puts @@bar } # error
于 2011-07-14T13:28:24.107 に答える
0

次に例を示します(ActiveRecordを考えてください)。

class Base
  def connect(connection)
    @@connection = connection
  end

  def connection
    @@connection
  end
end

class User < Base
end

class SuperUser < User
end

Base.new.connect("A connection")
puts User.new.connection      #=> A connection
puts SuperUser.new.connection #=> A connection

ここでの秘訣は、クラス変数がインスタンスメソッドからアクセス可能であり、継承されることです。これを試して:

class Base
  def self.connect(connection)
    @connection = connection
  end

  def self.connection
    @connection
  end

  def connection
    self.class.connection
  end
end

class User < Base
end

Base.connect("A connection")
puts User.new.connection #=> nil

(クラスから)独自のクラスインスタンス変数にアクセスしようとすると、継承されませnilん。self.connectionUser

追加:はい、誤用すると危険な場合があります:

@@a = "A"

class A
  def self.a
    @@a
  end
  def a
    @@a
  end
end

puts A.a     #=> A
puts A.new.a #=> A
于 2011-07-14T16:07:55.383 に答える