2010-08-02 47 views
1

我有一個名爲AB的模塊。現在它看起來是這樣的:模塊中的動態方法?

module AB 
    extend self 

    def some_method(hash) 
     .... 
    end 

    .... 
end 

我們用這樣的:AB.some_method(:東西=>:什麼,:等=> '你的想法')。有大約六個字符串,用戶必須通過,我想變成動態方法,以便代替AB.some_method(:thing =>:無論...)他們只需調用AB。無論(...)還是AB :: whatever(...)。我以爲我可以用method_missing做到這一點,但我想我不明白。我做了這樣的事情:

module AB 
    def method_missing(name,*args) 
     super unless THINGS.include?(name.to_s) 
     ... 
    end 
end 

但是我試圖調用AB :: whatever時從來沒有進入該方法。我想過關於遍歷THINGS和使用define_method,但我不知道如何定義帶參數的方法。

任何幫助表示讚賞。

+0

學會給予好評你喜歡:) – horseyguy 2010-09-12 06:08:26

回答

0

我認爲你可以使用兩種不同的方法,一種是動態定義方法,另一種是依靠method_missing。這裏有兩個例子:

# first approach, define methods 
class MyClassDefine 
    def some_method args 
    p args 
    end 

    [:foo,:bar].each do |name| 
    define_method name do |args| 
     # assume args is a hash, fix me 
     some_method args.merge({:thing => name}) 
    end 
    end 
end 

# second approach, use method_missing 
class MyClassMissing 
    def some_method args 
    p args 
    end 

    def method_missing name, args 
    super unless [:foo, :bar].include? name 
    # again, assuming argument is a hash 
    some_method args.merge(:thing => name) 
    end 
end 

mcd = MyClassDefine.new 
mcd.foo :etc => 'you get idea' 
#=> {:etc=>"you get idea", :thing=>:foo} 

mcm = MyClassMissing.new 
mcm.foo :etc => 'you get idea' 
#=> {:etc=>"you get idea", :thing=>:foo} 

這裏要做的事情是覆蓋當方法被傳遞別的東西而不是散列作爲參數的情況。

+0

請問你的答案意味着你只能使用一個類(而不是模塊)做的答案?這是我在你的版本中看到的唯一區別。 – Sam 2010-08-02 19:05:03

+0

我認爲問題在於你在你的例子中混合了類和實例方法:'some_method'既是實例又是類方法,'method_missing'是一個實例方法,並且你試圖調用'whatever'作爲一個類方法。 – 2010-08-02 19:23:29

+0

正如我所說,我很高興打電話給AB :: whatever或AB.whatever ...我不在乎。在模塊中使用method_missing時似乎都不起作用。 – Sam 2010-08-02 19:50:08

4

第二個代碼示例中的問題是method_missing應該聲明爲self.method_missing。如預期了以下工作:

module AB 
    THINGS = %w(whatever) 

    def self.method_missing(name, *args) 
    super unless THINGS.include?(name.to_s) 
    "responding to #{name}" 
    end 
end 

p AB.whatever #=> "responding to whatever" 
p AB.something #=> NoMethodError 
+1

感謝這正是我想要的。 – Sam 2010-08-03 23:30:38