2017-01-13 4 views
4

定数NAMEとメソッドhelloを含むモジュールを作成しました。クラスにモジュールが含まれている場合は、両方の定義を異なるスコープで表示する必要があります。モジュールを定数を固有クラス内でも見えるようにする方法は?

module A 
    NAME = 'Otto' 
    def self.included(base) 
    base.extend(ClassMethods) 
    end 

    def hello(name = 'world') 
    self.class.hello(name) 
    end 

    module ClassMethods 
    def hello(name = 'world') 
     "Hello #{name}!" 
    end 
    end 
end 

class B 
    include A 

    def instance_scope 
    p [__method__, hello(NAME)] 
    end 

    def self.class_scope 
    p [__method__, hello(NAME)] 
    end 

    class << self 
    def eigen_scope 
     p [__method__, hello(NAME)] 
    end 
    end 
end 

B.new.instance_scope 
B.class_scope 
B.eigen_scope 

#=> script.rb:34:in `eigen_scope': uninitialized constant Class::NAME (NameError) 
    from script.rb:41 

しかし定数はeigenclassのインスタンスメソッドの範囲、class << selfに表示されません。

モジュールをより堅牢にし、上記のエラーのある範囲でも定数を提供する方法はありますか?

+0

感謝を。私は何か新しいことを学んだ! –

+0

@EricDuminilまったくありません!あなたの説明は非常に便利です。 – sschmeck

答えて

4

ソリューション

class << self 
    def eigen_scope 
    p [__method__, hello(self::NAME)] 
    #=> [:eigen_scope, "Hello Otto!"] 
    end 
end 

なぜself::NAME動作しますか?

  • A::NAMEは、最も簡単でハードコードされたバージョンです。 Bインスタンスを:
  • B::NAMEBeigen_scopeインサイドA
  • が含まれているためにもself、働くだろうがinstance_scopeでは動作しませんので、self::NAME作品だけでなく
  • self::NAMEself.class_scope
  • self::NAMEに働くだろう、Bですクラス/モジュールではありません。

NAMEはなぜ機能しませんか?

Here非常に良い説明です。

定数ルックアップ Module.nestingModule.nesting.first.ancestorsで定義された定数を検索し、 Object.ancestorsModule.nesting.first場合はゼロであるか、またはモジュール

selfclass_scopeeigen_scopeにおいても同様です。

Module.nestingはしかし異なっている:eigen_scope

ためclass_scope

  • [#<Class:B>, B]ため

    • [B]のでModule.nesting.first.ancestorsは次のとおりです。

      • [B, A, Object, Kernel, BasicObject] FO eigen_scope

      AためのR class_scope

    • [#<Class:B>, A::ClassMethods, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]検索、しかしA::ClassMethodsされていません!

      だからあなたが定義することができます。興味深い質問について

      module A 
          module ClassMethods 
          NAME = 'Bob' 
          end 
      end 
      
  • +0

    説明をありがとう。 'hello_name(NAME)'も固有クラス内で動作するようにモジュールを適合させる方法はありますか? – sschmeck

    +0

    申し訳ありませんが、私はその質問を理解していません。 –

    +1

    なぜ定数ルックアップがこのような奇妙な動作をするのか? class_scopeの内部ではうまくいきますが、 'self'はどちらの場合も同じですか? – Ilya

    関連する問題