我不確定你想要從你的例子中做什麼。作爲一般規則,在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 #=> {}
如果此答案不包括解決方案,它應該至少引導您更接近!
來源
2011-03-24 02:03:13
Tom
對於元編程嘗試http://pragprog.com/titles/ppmetr/metaprogramming-ruby – blu 2011-03-23 16:12:05
感謝您的幫助 – maxiperez 2011-03-23 17:41:19