2011-10-04 32 views
1

我對Ruby比較陌生,但是在有很多重複方法的情況下。在試圖幹出我的代碼,我想出了類似以下內容:動態方法在define_method中調用

class Foobar 
    def some_method 
    # 
    end 

    def some_method2 
    # 
    end 

    def some_calculation 
    # 
    end 

    [:some_method_test, :some_method2_test].each do |method| 
    define_method method do 
     return self.send(method.to_s.chomp "_test")/some_calculation 
    end 
    end 
end 

我的問題是關於.to_s.comp--有沒有寫這個,完成我的目標的另一種方式?

回答

2

是的,您可以從原始名稱開始。

[:some_method, :some_method2].each do |method| 
    define_method :"#{method}_test" do 
    return self.send(method)/some_calculation 
    end 
end 

請注意,這種元編程通常沒有多大意義,除非您有很多不重要的方法。

2

你可以嘗試減少平凡方法的數量。也許你可以用generic_method(attribute_desired)取代some_methodsome_method2some_method3在那裏你會打電話generic_method(1)代替some_method,調用generic_method(2)代替some_method2

有時測試可以告訴你的東西 - 這就是被測試的代碼。如果測試非常無聊,也許這意味着正在測試的代碼太無聊了,並且有太多重複。

1

這裏是另一種解決方案:

class Foobar 
    # Non-test method definitions ... 

    %w(some_method some_method2).each do |mthd| 
    class_eval(<<-EOS, __FILE__, __LINE__ + 1) 
     def #{mthd}_test 
     #{mthd}/some_calculation 
     end 
    EOS 
    end 
end 

通過這種方式,該方法定義本身是有點慢,但運行得更快,因爲他們所謂的無反射法像send,有蹤跡較淺。

BTW,%w(foo bar)代表單詞,並且產生['foo', 'bar']

<<-EOS 
    blah blah 
    blah blah 
EOS 

只是一個字符串,分散多行(HERE doc)。

class_eval在當前類(類Foobar)的上下文中將字符串評估爲腳本。 __FILE____LINE__ + 1影響堆棧跟蹤中的文件路徑和行號。