2009-01-16 75 views
7

我試圖動態定義,通過另一個函數,它接受一個選項參數調用函數:是否可以在Ruby中使用可選參數定義一個塊?

class MyClass 
    ["hour", "minute", "second"].each do |interval| 
    define_method "get_#{interval}" do |args| 
     some_helper(interval, args) 
    end 
    end 
    def some_helper(interval, options={}) 
    # Do something, with arguments 
    end 
end 

我希望能夠調用這兩個方面對MyClass的不同方法(與和無可選參數):

mc = MyClass.new 
mc.get_minute(:first_option => "foo", :second_option => "bar") 
mc.get_minute # This fails with: warning: multiple values for a block parameter (0 for 1) 

在第二呼叫,以分鐘,我看到這樣的警告:

警告:多個值塊參數(0 1)

  1. 是否有寫爲「*的get_」方法塊,使此警告不會拿出一個辦法?
  2. 我在濫用define_method嗎?

回答

16

您需要進行的唯一更改是將args更改爲*args*表示args將包含該塊的可選參數數組。

+0

感謝您指出了這一點! – Readonly 2009-01-16 21:30:23

0

我同意戈登加入你的參數將使它消失。

這樣做的另一種方法是使用的method_missing()

事情是這樣的:

class MyClass 

    def method_missing(m, *args) 
    if /get_(.+)/.match(m.to_s) 
     some_helper($1, args) 
    else 
     raise 'Method not found...' 
    end 
    end 

    def some_helper(interval, *args) 
    puts interval + ' -> ' + args.inspect 
    end 

end 

m = MyClass.new 
m.get_minute(:first_option => "foo", :second_option => "bar") 
+1

我寧願在缺少方法時調用'super'而不是'raise',以便在方法真的丟失時執行默認的Ruby操作。 – Priit 2009-01-18 17:06:32

5

兩年後...... 我不知道,如果是與紅寶石的一項新功能1.9.2,或者如果它是也可以過去,但這個工程:

class MyClass 
    ["hour", "minute", "second"].each do |interval| 
     define_method "get_#{interval}" do |args = {:first_option => "default foo", :second_option => "default bar"}| 
      some_helper(interval, args) 
     end 
    end 
    def some_helper(interval, options={}) 
     # Do something, with arguments 
     p options 
    end 
end 

mc = MyClass.new 
mc.get_minute(:first_option => "foo", :second_option => "bar") 
mc.get_minute 

結果是:

{:first_option=>"foo", :second_option=>"bar"} 
{:first_option=>"default foo", :second_option=>"default bar"} 
+2

是的,具有默認值的可選參數對於Ruby 1.9來說是新的 – 2011-03-27 22:24:58

相關問題