1

モジュールのメソッドをクラスにインクルードしようとしていますが、インクルードを行っている基本クラスのクラス変数にアクセスするメソッドが含まれていますが、想定どおりに動作しません。コード:

class Awesome
    @@name = "ME!"
end

module MyGem
    module Namespace
        def typist
            puts @@name
        end
    end
end

if defined? Awesome
    Awesome.class_eval do
        include MyGem::Namespace
    end
end

Awesome.new.typist # Test our new 'injected' instance method!
#=> NameError: uninitialized class variable @@name in MyGem::Namespace

私の Ruby のinclude動作の理解は明らかに不安定です。インクルードはメソッドを基底クラスに組み込み、実行コンテキストは基底クラスになると考えていましたが、エラー メッセージは、含まれているメソッドの実行コンテキストがオリジナルにあることを暗示しているようです。メソッドのモジュール。

では、コード スニペットに示されているように、どうすればやりたいことを達成できるでしょうか? クラス変数を、インスタンス変数を使用するなど、他の実装に置き換えたり、それを機能させるために必要な方法で置き換えたりできれば幸いです:)。

4

1 に答える 1

1

クラス変数のルックアップをメソッド呼び出しの結果にすると、次のように機能します。

def typist
  puts self.class.class_variable_get(:@@name)
end

残念ながら、クラス変数がこのように機能する理由を説明するのに十分ではなく、他の方法では機能しない. Ruby の世界ではクラス変数が比較的人気がないことは知っています。私の直感では、モジュール内でクラス変数を定義できるため (クラスは から継承されModuleます)、モジュール内の変数を参照すると、そのモジュール内が自動的に検索されます。ルックアップ メッセージを送信先のインスタンスのクラスに明示的に送信:typistすると、正しい変数が確実に見つかります。

于 2013-05-22T18:45:17.800 に答える