2017-11-10 22 views
3

私は外の宝石の周りを優雅で孤立した形で包み込む必要があります。下の抽象化を考えると、すべてがスムーズに実行されますが、「バー」は決して印刷されません。 誰かが私にその理由を教えてもらえますか?gemのクラスメソッドを絞り込みます

マイコード:

module RefineGem 
    refine GemMainModule::GemClass do 
    def self.foo 
     p 'bar' 
     super 
    end 
    end 
end 

module Test 
    using RefineGem 

    def test 
    GemMainModule::GemClass.foo 
    end 
end 

class Testing 
    include Test 
end 

Testing.new.test 

宝石コード:

module GemMainModule 
    class Base 
    include GemMainModule::Fooable 
    end 

    class GemClass < Base 
    end 
end 

module GemMainModule 
    module Fooable 
    extend ActiveSupport::Concern 

    class_methods do 
     def foo 
     p 'zoo' 
     end 
    end 
    end 
end 
+0

をモジュールを付加する方法、クリーナー堅牢であるため、私は 'refinements'を使用したことがないとインテリジェントなアプローチ。私はあなたに 'GemMainModule :: GemClass.singleton_class {def foo ... end}'を改良するよう提案します。私は洗練されたものがクラスメソッドのために働くのか疑問です。 – mudasobwa

+0

是非、ソリューションとしてモジュールを答えとして投稿してください。私はそれを受け入れます。 – fabriciofreitag

+0

「モデルを使用する」とはどういう意味ですか? – mudasobwa

答えて

2

私は改良がクラスメソッドのために働く疑い。あなたはしかしsingleton_classを絞り込むことがあります

module RefineGem 
    refine GemMainModule::GemClass.singleton_class do 
    def foo 
     p 'bar' 
     super 
    end 
    end 
end 

を私は個人的に同じ機能を達成するためにModule#prependを使用することを好む:

GemMainModule::GemClass.singleton_class.prepend(Module.new do 
    def foo 
    p 'bar' 
    super 
    end 
end) 
+0

私はこれが好きで、私が迷惑をかけて、自分の状況に欠けているポイントを1つだけ上げてしまうと、うまくいきます。 (洗練されたものと同じように、「キーワード」を使用している)、特定の場所や他の場所で動作を上書きしたい。 – fabriciofreitag

+0

いいえ、 'Module#prepend'であなたはそれを行うことができません。正直なところ、私は決して使用範囲に対処する必要性を感じなかった。さらに、それは直感的ではないと誤解を起こしやすいと思います。ここでは 'foo'がこのように動作し、そこではそれが動作します。 – mudasobwa

関連する問題