2017-09-06 5 views
0

私はRubyの基本的な質問があります。なぜなら、自分自身を拡張してモジュールを作成すると、attr_accessorが完璧に動作する理由が分かりません。なぜattr_accessorはextend selfでモジュールで動作しますか?

私が知る限り、attr_accessorはインスタンスクラスで動作するはずですが、一部のreasoneではこれらのモジュールで動作しています。ここで

だから例

module A 
    extend self 
    attr_accessor :custom_method 

    def foo 
    self.custom_method 
    end 
end 

A.custom_method # => nil 
A.foo # => nil 
A.custom_method = "bar" # => "bar" 
A.custom_method # => "bar" 
A.foo # => "bar" 

で、何がA.custom_methodに起こるのだろうか?それは今からアプリケーション全体にわたって "バー"になるでしょうか?

Aのこの「インスタンス」をどのように破壊できますか?

+0

_ "私は基本的な質問があります。" _ _ ''拡張自己 'は無邪気でシンプルに見えますが、結果は非常に気になるものです。何が起きているのかを理解するには、 'obj = Object.new;のように、その行を削除して別のオブジェクトを拡張する方が簡単かもしれません。 obj.extend(A) '。 – Stefan

+0

'extend'とは何ですか? –

答えて

3

モジュールには2つのコンテキストがあり、「インスタンス」コンテキストはmixinメソッドを参照しています。 extend selfを呼び出すと、モジュール上で直接mixinメソッドを呼び出せるようになります。デフォルトでは

module Example 
    def mixin_level 
    :mixed 
    end 

    def self.module_level 
    :module 
    end 
end 

あなただけの右のコンテキストでこれらを呼び出すことができます。

Example.module_level 
# => :module 

Example.mixin_level 
# => NoMethodError: undefined method `mixin_level' for Example:Module 

あなたがextend selfトリックを行う場合は、mixin_level方法、およびそのコンテキストで任意の他の人が、また動作します。モジュールレベルをミックスインのスーパーセットにしています。

A定数を削除するのは簡単ではありません。それはシングルトンです。

メモとして、mattr_accesorは、extend selfを必要とせずに簡単に作成できます。

+0

優れた答えですが、データセットはattr_accessorに格納されていますか? –

+0

いつものように、その方法が実行されるのはいつでも「自己」です。これが他のオブジェクトが 'include'を呼び出したmixinメソッドである場合、そのオブジェクトに入ります。あなたが 'A.foo'について話しているなら、それはAオブジェクトに入ります:' 'instance_variables'(http://ruby-doc.org/core-2.4.1/Object)を介した' A.instance_variables'。 html#method-i-instance_variables)メソッドを使用してこれを反映させることができます。 – tadman

+1

ありがとう、あなた!あなたの答えは本当に役に立ちました! ;) –

関連する問題