2011-11-24 58 views

回答

5

您可以使用水木清華這樣的:

def make_class(s_value, method_name, &method_body)  
    Class.new do 
    define_method method_name, method_body  

    define_method :to_s do  
     s_value  
    end  
    end 
end  

klass = make_class 'foo instance', :foo do |*args|  
    "called foo with #{args.inspect}"  
end  

k = klass.new  
puts k.to_s     # => foo instance 
puts k.foo [1, 2], 'hello' # => called foo with [[1, 2], "hello"] 

在這種情況下,你應該通過你的方法的身體作爲一個塊(你可以用你想要的任何參數列表替換|*args|作爲你的方法的參數)。如果你想通過method_body而不是作爲一個塊,但作爲一個字符串,然後eval是你的朋友。

+0

剛剛運行此代碼段,它的工作原理。畢竟,元編程似乎並不那麼棘手。謝謝! –

0

我不建議這樣做,但你能...

def make_class(method_name, method_body, s_value) 
    eval(" 
    class Anonymous 
     def #{method_name}(args) 
      #{method_body}(args) 
     end 

     def to_s 
     return '#{s_value}' 
     end 
    end 
    ") 
end 

make_class(:bla, :puts, 'bla') 
Anonymous.new.bla('moin') 
puts Anonymous.new.to_s 

返回

moin 
bla 
2
def make_class(method_name, method_body, s_value) 
    Class.new { 
    define_method method_name do |*args| 
     eval(method_body) 
    end 

    define_method :to_s do 
     s_value 
    end 
    } 
end 

"Metaprogramming Ruby: Program Like the Ruby Pros"是學習ruby元編程的很好的書。

+0

感謝您的書,我會檢查出來。 –

1

我能想到的最簡單的方法:

def make_class(method_name, method_body, s_value) 
    klass = Class.new 
    klass.class_eval "def #{method_name} ; #{method_body} ; end" 
    klass.class_eval "def to_s ; #{s_value} ; end" 
    klass 
end 

用法:

>> Anonymous = make_class(:foobar, "puts 'foo'", 23) 
=> Anonymous 
>> a = Anonymous.new 
=> 23 
>> a.foobar 
foo 
=> nil 
>> a.to_s 
=> 23 

編輯:好吧,我有點過於簡單化這裏,這不處理該方法的ARGS。

相關問題