2011-12-21 42 views
0

我正在使用method_missing函數創建動態方法。 它的一切工作正常,但我想要做的是,將這些方法添加到ClassName.methods數組。代碼如下:將動態方法添加到class.methods數組

module MyObjectStore 
    values = [] 
    temp = {} 
    def self.included(kls) 
    kls.extend ClassMethods 
    end 

    ClassMethods = Module.new do 
    define_method :method_missing do |method,*args,&block|   
     if method =~ /find_by_/ 
     methods << method 
     add_search_method(method,*args) 
     else 
     values.send "#{method}", &block 
     end 
    end 
    define_method :add_search_method do |method,*args| 
     values.each do |obj| 
     x = obj.send "#{method.to_s.split('_')[-1]}" 
     if x == args[0] 
      p obj 
     end 
     end 
    end 
    end 

    define_method :add_check_attribute do |method,*args| 
    if method.to_s =~ /=$/ 
     temp[method[0..-2]] = args[0] 
    else 
     instance_variable_get("@#{method}") 
    end 
    end 
    define_method :method_missing do |method,*args| 
    add_check_attribute(method,*args) 
    end 
    define_method :save do 
    temp.each {|key,value| instance_variable_set("@#{key}",value)} 
    values << self 
    end 
end 

class C 
    include MyObjectStore 
end 

我將新方法添加到方法Array。它在這裏添加得很好。問題是,當我對C類進行引用並嘗試找到新添加的方法時,它不會返回任何內容。即

a = C.new 
a.id = 1 
a.name = 'gaurav' 
a.save 
C.find_by_name('gaurav') 
p a.methods.include?(:find_by_name) 

回報

有沒有一種方法,我可以去這樣做?

在此先感謝。

+0

這有一種過度元的方式給我做事情 - 當然,軌道做這樣的事情,但這並不容易維護:)。你能重構你的代碼來消除這個問題嗎?即使你找到了「修復」,它仍然很難理解和維護。 – Peter 2011-12-21 08:50:47

+0

嘿,彼得,謝謝你的迴應,甚至我覺得這個過分元的東西是一樣的。 但實際上,這是我的訓練練習之一,我必須這樣做,代碼維護無關緊要! :) 那麼,你認爲這樣的事情是可能的,或者我可以如何重組我的代碼? – 2011-12-21 09:38:43

回答

0

這裏,新方法是爲類C定義的類方法。 但'a'是C的一個實例,因此您看不到這些方法。

這將返回true

p a.class.methods.include?(:find_by_name) 

EDITED

你假設methods << method將方法添加到模塊,但它不會做這樣的事情。所以,你需要明確的定義方法是這樣,

ClassMethods = Module.new do 
    def method_missing(method, *args, &block)  
     if method =~ /find_by_/ 
     add_search_method(method,*args) 
     send(method, *args) 
     else 
     values.send "#{method}", &block 
     end 
    end 

    def add_search_method(method, *args) 
     define_singleton_method(method) do |*args| 
     @@values.each do |obj| 
      return obj if obj.send("#{method.to_s.split('_')[-1]}") == args[0] 
     end 
     nil 
     end 
    end 
    end 

與此一替換您ClassMethods定義和C.methods將包括方法的發現。

我不完全確定你要在這裏完成什麼,但正如Peter在他的評論中所建議的那樣,你可能需要重構代碼,因爲這看起來不太乾淨。

+0

不是,仍然說'虛假':\ – 2011-12-21 08:00:15

+0

感謝Dipil的啓發,但find_by_ *方法現在已停止工作! :\ – 2011-12-21 10:43:17

+0

感謝隊友,這個作品非常好,非常感謝你的幫助。 :) – 2011-12-21 11:26:50