質問

私は次のことを持っています:

class Test
    @@a = 10

    def show_a()
        puts "a: #{@@a}"
    end

    class << self
      @@b = '40'

      def show_b
        puts "b: #{@@b}"
    end
  end
end

なぜ次の仕事をするのか:

Test.instance_eval{show_b}
b: 40
=> nil

しかし、私はアクセスできません @@b 直接?

Test.instance_eval{ @@b }
NameError: uninitialized class variable @@b in Object

同様に、次の作品が機能します

t = Test.new
t.instance_eval{show_a}
a: 10
=> nil

しかし、以下は失敗します

t.instance_eval{ @@a }
NameError: uninitialized class variable @@a in Object

クラス変数に直接アクセスできない理由がわかりません instance_eval ブロック。

役に立ちましたか?

解決

私は、ルビカイギ党の間にマッツに同じ質問をしたばかりです。私は半酔っていましたが、彼は完全に冷静だったので、あなたはこれを決定的な答えとしてとることができます。

アントンは正しい - instance_eval()を介してクラス変数にアクセスできない理由は「理由」です。 Class_Eval()でさえ同じ問題を共有しています(Matz自身は、私がすでにそれを試してみたと彼に言ったまでClass_Eval()について完全に確信していませんでした)。より具体的には、スコープごとに、クラス変数はインスタンス変数よりも定数に似ているため、自己を切り替える(instance_eval()およびclass_eval()do)は、それらにアクセスすることに関して違いを生みません。

一般に、クラス変数を完全に回避することをお勧めします。

他のヒント

編集: 以下のコードは1.8.7と1.9.1でテストされました... 1.9.2:/で状況が再び異なるようです

状況は実際にはそれほど簡単ではありません。 1.8または1.9を使用しているかどうか、および使用しているかどうかに応じて、行動には違いがあります class_eval また instance_eval.

以下の例は、ほとんどの状況での動作の詳細を示しています。

また、その動作はクラス変数と類似しているがまったく同じではないため、定数の動作を適切な尺度に含めました。

クラス変数

class_eval Ruby 1.8で:

class Hello
    @@foo = :foo
end

Hello.class_eval { @@foo } #=> uninitialized class variable

class_eval Ruby 1.9で:

Hello.class_eval { @@foo } #=> :foo

したがって、クラス変数 それは 使用するときに1.9(ただし1.8ではそうではない)で調べた class_eval

instance_eval Ruby 1.8で 1.9

Hello.instance_eval { @@foo } #=> uninitialized class variable
Hello.new.instance_eval { @@foo } #=> uninitialized class variable

クラス変数はそうです いいえ 1.8で見上げました また 1.9使用する場合 instance_eval

また、興味深いのはそうです 定数:

定数

class_eval Ruby 1.8で

class Hello
    Foo = :foo
end

Hello.class_eval { Foo } #=> uninitialized constant

class_eval Ruby 1.9で

Hello.class_eval { Foo } #=> :foo

したがって、クラス変数と同様に、定数は1.9で見上げられますが いいえ 1.8で class_eval

instance_eval Ruby 1.8で

Hello.instance_eval { Foo } #=> uninitialized constant
Hello.new.instance_eval { Foo } #=> uninitialized constant

instance_eval Ruby 1.9で

Hello.instance_eval { Foo } #=> uninitialized constant
Hello.new.instance_eval { Foo } #=> :foo

一定のルックアップは、クラス変数とはまったく類似していないようですRuby 1.9を探しています。 a Hello 実例 します 中に定数にアクセスします Hello クラスはそうではありません。

まあ、おそらく最良の答えは「ちょうど」という理由です。私はそれが少し奇妙に聞こえることに同意しますが、それはそれが何であるかです。

文字列でinstance_evalを実行すると、メソッドがクラス変数にアクセスしようとするという警告が表示されます。

irb(main):038:0> Test.new.instance_eval "@@a"
(eval):1: warning: class variable access from toplevel singleton method
NameError: (eval):1:in `irb_binding': uninitialized class variable ...

Ruby 2.1

これは、クラス変数にアクセスすることがわかった最も簡潔で意味的に正しい方法です。

class Hello
    @@foo = :foo_value
end

Hello.class_variable_get :@@foo  #=> :foo_value
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top