2017-02-01 17 views
1

クラスに含まれている場合、インスタンスメソッドとクラスメソッドの両方を含むモジュールがあります。インスタンスメソッドとクラスメソッドは両方ともクラス変数にアクセスするものとする。モジュールクラスとインスタンスメソッドのクラス変数へのアクセス

module MyModule 
    @@a_class_variable = "lorem ipsum" 

    def self.included(base) 
    base.extend ClassMethods 
    end 

    module ClassMethods 
    def a_class_method 
     @@a_class_variable << "abc" 
    end 
    end 

    # Use it in constructor 
    def initialize 
    @@a_class_variable << "abc" 
    end 

    def an_instance_method 
    @@a_class_variable << "abc" 
    end 
end 

私はいくつかのクラスでMyModuleを含め、インタプリタは言う:NameError:MyModuleというにおける初期化されていないクラス変数@@ a_class_method ::クラスメソッド

は私が間違って何をしているのですか?

答えて

0

MyModule::ClassMethodsの場合、MyModuleには入らず、@@a_class_variableにアクセスできません。 Here'sに関連する質問。アクセサで

、あなたのコードは正常に動作します:

module MyModule 
    @@a_class_variable = "lorem ipsum" 

    def self.a_class_variable 
    @@a_class_variable 
    end 

    def self.included(base) 
    base.extend ClassMethods 
    end 

    module ClassMethods 
    def a_class_method 
     MyModule.a_class_variable << " abc1" 
    end 
    end 

    # Use it in constructor 
    def initialize 
    @@a_class_variable << " abc2" 
    end 

    def an_instance_method 
    @@a_class_variable << " abc3" 
    end 
end 

class MyObject 
    include MyModule 
end 

my_object = MyObject.new 
MyObject.a_class_method 
p my_object.an_instance_method 
#=> "lorem ipsum abc2 abc1 abc3" 

あなたはコメントで述べたように、それは国民に@@a_class_variableを公開しています。 方法をprivateまたはprotectedに設定すると、ClassMethodsMyModuleは関連していないため、上記の例では機能しません。

それはきれいな解決策ではないかもしれませんが、あなたはプライベートメソッドにアクセスするためにsendを使用することができます。あなたの答えのための

module MyModule 
    @@a_class_variable = 'lorem ipsum' 

    module ClassMethods 
    def a_class_method 
     MyModule.send(:__a_class_variable) << ' abc1' 
    end 
    end 

    # Use it in constructor 
    def initialize 
    @@a_class_variable << ' abc2' 
    end 

    def an_instance_method 
    @@a_class_variable << ' abc3' 
    end 

    class << self 
    def included(base) 
     base.extend ClassMethods 
    end 

    private 

    def __a_class_variable 
     @@a_class_variable 
    end 
    end 
end 
+0

感謝を!これは実際に実行可能にしますが、クラス変数を公開します。機能を保持し、クラス変数privateへのアクセスを維持することはありませんか?私がクラスに入っていると、インスタンスとクラスの両方のメソッドから直接クラス変数にアクセスできます。 – nsommer

+0

あなたは完全に正しいです。私は答えを更新しました。 –

+0

私は今、ClassMethodsのメソッドとメソッドの違いを理解していると思います。私は違いがないと思ったが、そこにある。また、レールからコードの一部(ActiveSupportのコールバックなど)を検索し、提案したもの(アクセサメソッド)とまったく同じように実装したようです。私はそれを前に理解しようとしましたが、今まで失敗しました。すべてこれが私が望んでいたものではありません(読んでください:コードは私が期待していたほどきれいではありません)。しかし、それはあなたのせいではないので、私は答えを受け入れます。 – nsommer

関連する問題