2009-07-10 39 views
3

是否可以使用字符串(方法名稱)和塊(方法的內容)在ruby中定義實例方法?來自字符串和塊的Ruby實例方法

我想這將需要使用instance_eval(),但我還沒有想出如何混合兩種數據類型呢。字符串和塊都是動態確定的,所以它會在開始時用「def#{string}」創建塊 - 我不知道該怎麼做。

我的用例是一個代表Bacula配置文件的類。配置文件可以有許多不同類型的資源。它們都存儲在幕後的相對複雜的數據結構中(出於其他原因,簡化這種結構不會完成我所期望的)。我想通過命名方法快速訪問資源。

例如,A代表一個配置文件,B代表另一個配置文件。 A有資源總監,客戶,工作和B有消息和主任。在這種情況下,A應該有方法director(),client()和job(),而B有消息()和director()。其中每一個都會從對象的相應配置文件中返回相關資源。

我知道有這樣做的更簡單的方法(如執行[]方法),但在這一點上,我追求更好的解決方案,好奇的緣故。

+0

你能舉一個快速的例子來說明你想要的方法嗎?局域網使用它? – 2009-07-10 16:35:06

+0

添加用例。 – 2009-07-10 16:53:17

回答

4

我想你要找的是方法define_method on Module;然而,它是私人的,所以你必須使用class_eval或其他東西來運行它。

body = proc { self * 3 } 
name = "triple" 
c = Numeric 

c.class_eval { define_method(name.to_sym, &body) } 

3.triple # 9 

而且隨着參數的方法:

body = proc { |second| [self * 3, second * 3] } 
name = "triple_both" 
c = Numeric 

c.class_eval { define_method(name.to_sym, &body) } 

puts 3.triple_both(5) # [9, 15] 

要換上新的方法,一個單獨的對象(或Eigenclass,或不管他們叫):

body = proc { puts @meme + @meme + @meme } 
name = "meme" 
class SwedishChef; def initialize; @meme = "bork"; end; end  
sc = SwedishChef.new 
(class << sc; self; end).class_eval { 
    define_method(name.to_sym, &body) 
} 
sc.meme # borkborkbork 

[編輯(JörgW Mittag):我修正了單例方法的例子。]