2010-01-10 156 views
12

我想弄清楚如何動態地創建方法紅寶石class_eval方法

class MyClass 
    def initialize(dynamic_methods) 
    @arr = Array.new(dynamic_methods) 
    @arr.each { |m| 
     self.class.class_eval do 
     def m(*value) 
      puts value 
     end 
     end 
    } 
    end 
end 

tmp = MyClass.new ['method1', 'method2', 'method3'] 

可惜,這只是創建方法M,但我需要的基礎上男,思想創造價值的方法呢?

回答

27

有兩種接受的方式:

  1. 使用define_method

    @arr.each do |method| 
        self.class.class_eval do 
        define_method method do |*arguments| 
         puts arguments 
        end 
        end 
    end 
    
  2. 使用class_eval一個字符串參數:

    @arr.each do |method| 
        self.class.class_eval <<-EVAL 
        def #{method}(*arguments) 
         puts arguments 
        end 
        EVAL 
    end 
    

第一個選項將閉包轉換爲方法,第二個選項評估字符串(heredoc)並使用常規方法綁定。第二個選項在調用方法時具有非常輕微的性能優勢。第一個選項(可以說)更具可讀性。

+0

謝謝,正是我需要的 – Bob 2010-01-10 23:28:30

+0

你可能想要注意到你需要更加小心關於第二種方法,例如避免像https://github.com/rails/rails/blob/f1d8f2af72e21d41efd02488f1c2dcf829e17783/actionpack/lib/action_dispatch/routing/route_set.rb#L188-200這樣的代碼 – 2013-01-31 19:18:33

4
define_method(m) do |*values| 
    puts value 
end 
+0

太棒了,這有效,但我如何指定值作爲可選參數? – Bob 2010-01-10 23:25:52

+0

哦,只是像這樣添加一個「*」? define_method(m)do | * value | – Bob 2010-01-10 23:27:08

+1

對(我剛剛編輯它)。請注意,* value不代表「value是一個可選參數」。這意味着「value是一個包含所有參數(其中可能有任意數字)的數組。」 – sepp2k 2010-01-10 23:28:17