2011-03-23 57 views
0

編程,我試圖讓一個通用的方法:元/動態/通用在紅寶石

class Foo 
    attr_reader 

    def add(object) 
    item = @item.find { |item| item.(#the method is calling object.class) == object if item.is_a?(object.class)} 
    end 
end 

我想創造出不同的參數類數組的元素比較通用的方法。

實施例:

item.method1 == method1 if item.is_a?(method1.class) 

其中方法1是類的名稱。

另外,我需要一個關於元編程和動態/泛型編程的完整教程。

+1

對於元編程嘗試http://pragprog.com/titles/ppmetr/metaprogramming-ruby – blu 2011-03-23 16:12:05

+0

感謝您的幫助 – maxiperez 2011-03-23 17:41:19

回答

4

我不確定你想要從你的例子中做什麼。作爲一般規則,在Ruby中,您不檢查類型。它是動態類型的原因:您可以編寫適用於任何碰巧支持您的代碼調用方法的對象的代碼。

從我可以從你的意見告訴,你想擴展類Array所以,當你調用像an_array.pack陣列上的方法,該陣列中搜索的Pack一個實例並返回。 Ruby有一種方法,只要發現方法不存在,稱爲Module#method_missing。例如,如果我隨機決定調用4.to_dragon(magic: 4, height: 700),則Ruby解釋器將嘗試將to_dragon作爲在Fixnum(數字類型)繼承鏈中某些類或模塊上定義的公共方法。假設您沒有對鏈條做過任何奇怪的事情,我們會通過以下參數調用method_missing對象4[:to_dragon, { magic: 4, height: 700 }]。基本上,這是名稱附加到參數的前面,應該給出一個塊。

使用這種技術,你可以覆蓋method_missing得到這個代碼的解決方案:

class String 
    def method_to_class 
    split('_').map(&:capitalize).join 
    end 
end 

class Array 
    def method_missing(method_name, *arguments, &block) 
    find do |element| 
     element.class.name == method_name.to_s.method_to_class 
    end || super 
    end 
end 

您添加一個方法來String的方法名轉換爲一個類名。然後,您在Array上重新定義method_missing以檢查每個元素,以查看類名是否與給定類名匹配。如果找到了,那麼返回。否則(我們使用Ruby的花式||運算符執行此操作),則從該函數返回的值爲nil,並返回||的第二個操作數。這恰好是method_missing(我們通過super關鍵字獲得)的默認實現,並返回該呼叫應得的錯誤。

唯一的潛在問題是,如果您的元素名稱與已經在數組中定義的方法名稱相同,那麼將調用這些元素,而不是使用此特殊技術。例如,調用an_array.hash將爲您提供數組的散列碼,而不是散列的第一個實例。

在這方面更安全的技術更類似於我認爲你想要做的事情。實際上它使用類對象,你可以用它來覆蓋其他方法:

class Array 
    def add(class_object) 
    class << self 
     define_method class_object.name do 
     find do |element| 
      element.is_a? class_object 
     end 
     end 
    end 
    end 
end 

這直接對數組的一個實例定義了新的方法。例如:

an_array = [Array, Hash, Dragon].map &:new 
an_array.add Hash 
an_array.hash #=> {} 

如果此答案不包括解決方案,它應該至少引導您更接近!

+0

方法的名稱是類的名稱。例如我將一個包和一個產品保存在一個數組中,所以我使用array.pack或array.product我可以問參數對象is_a?(Class),但我想製作一個接受任何東西的泛型方法。如果我的意見不明確,請回​​答我。 – maxiperez 2011-03-28 15:12:37

+0

有一種有趣的方式可以通過元編程實現,我現在將添加它。 – Tom 2011-03-29 00:03:24