2013-11-24 156 views
2

我正在擴展一個類來接受DSL。實例應始終使用默認值進行響應,但代碼可能會更改。下面的代碼工作正常時,我打電話who_am_i,其中設置i_am方法,但我不知道如何設置默認方法。模塊同時擴展和包含?

module Helper 
    def i_am 
    "Default code" 
    end 
    def who_am_i 
    class_eval(<<-EOS, __FILE__, __LINE__ + 1) 
     def i_am 
     "This was executed in class: \#{self.class.to_s}" 
     end 
    EOS 
    end 
end 

class Test 
    extend Helper 
end 

t = Test.new 
t.i_am 

我可以這樣做,使這項工作:

class Test2 
    extend Helper 
    include Helper 
end 

t2 = Test2.new 
t2.i_am 

但是這似乎不可思議。思考?

+0

只是可以肯定,你想i_am是一個實例方法和who_i_am是一個類方法,對不對? – BroiSatse

+0

@BroiSatse我想通了...... – Daniel

回答

3

您需要使用包含方法/鉤。每次將模塊包含到其他類或模塊中時,它都會運行,並且此類或模塊用於參數。在你的情況下,你想︰

module Helper 
    def i_am 
    "Default code" 
    end 

    def self.included mod 
    mod.extend ClassMethods 
    end 

    module ClassMethods 
    def who_am_i 
     class_eval(<<-EOS, __FILE__, __LINE__ + 1) 
     def i_am 
      "This was executed in class: \#{self.class.to_s}" 
     end 
    EOS 
    end 
    end 
end 

class Tester 
    include Helper 
end 
+0

我想,我想就像你一樣。謝謝!我檢查了你的答案 – Daniel

1

啊哈!

答案是使用module.included()使它擴展類。這樣你可以使用「include Helper」,並且「include」部分將調用「Helper.included」,並且通過調用者,並用它來擴展它!

參考:http://www.railstips.org/blog/archives/2009/05/15/include-vs-extend-in-ruby/

module Helper 

    def i_am 
    "Default code" 
    end 

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

    module ClassMethods 
    def who_am_i 
     class_eval(<<-EOS, __FILE__, __LINE__ + 1) 
     def i_am 
      "This was executed in class: \#{self.class.to_s}" 
     end 
    EOS 
    end 
    end 
end 


class Test 
    include Helper 
end