我想在ruby中編寫一個方法,它接受某個方法的類並通過添加方法或更改現有方法的工作方式來修改其行爲。我想以不修改基類的方式做到這一點,所以基本上我想要一個函數,它接受一個類並返回一個新的修改後的類,而不會損害初始類。我很確定這是可能的,但我不確定從哪裏開始。ruby類擴展
1
A
回答
2
你有幾個選擇:
- 可以使用
x = Class.new(Parent) { def meth; puts "hello"; super; puts "bye"; end }
動態地定義一個類並重寫方法(&定義新) - 可以使用
Delegator
所以對於例如,如果您想動態創建記錄某些方法調用的類:
class Class
def logging_subclass(*methods)
Class.new(self) do
methods.each do |method|
define_method(method) do |*args,&blk|
puts "calling #{method}"
ret = super(*args,&blk)
puts "#{method} returned #{ret.inspect}"
ret
end
end
end
end
end
class One
def foo
"I'm foo!"
end
end
# this prints nothing
One.new.foo #=> returns :foo
# this prints:
# > calling foo
# > foo returned "I'm foo!"
One.logging_subclass(:foo).new.foo #=> returns :foo
請注意,您需要ruby 1.9來支持捕獲do |&blk|
(捕獲塊參數中的塊)。
1
我建議使用inheritance或a mixin;在我看來,使用mixin會是一個明智的想法,儘管使用繼承對於新手來說更容易。請記住,您可以始終從類繼承並更改行爲,或根據需要用新代碼包裝它。
class Mammal
def speak
"..."
end
end
class Cat < Mammal
def speak
"meow"
end
end
class Lion < Cat
def speak
"get ready for a big " + super + "!"
end
end
module Asexual_Critter
def reproduce(critter_list)
puts "*poink!*"
critter_list << self.clone
end
end
class Mutated_Kitty < Cat
include Asexual_Critter # inane example I know, but functional...
end
只要記住,如果你要玩這個不要做:
critters = [Mutated_Kitty.new]
begin
critters.each { |c| c.reproduce(critters) }
end while critters.length > 0
不然你,直到你用完的RAM,或者段錯誤漫長的等待是英寸
0
對不起,如果我理解你的問題錯了,但谷歌「紅寶石dsl」,你可能會發現這個事情對你的問題非常有用。 也在這裏查看關於這件事的問題。
看看這篇文章,如果你不知道如何開始:
[http://www.jroller.com/rolsen/entry/building_a_dsl_in_ruby][1]
我不喜歡的東西,以前通過保存我到一個文本文件中所作的更改,並從頭再來當讀取該文件該程序重新啓動或重新加載它的設置。
相關問題
- 1. Ruby擴展爲對象類
- 2. Ruby擴展NilClass
- 3. 如何用c擴展名擴展我的ruby類?
- 4. 擴展Ruby類(散)的新功能(recursive_merge)
- 5. Ruby擴展Data_Wrap_Struct - 類型錯誤
- 6. Ruby:一個擴展模塊的類
- 7. Ruby擴展Date類添加新方法
- 8. Ruby - 類中的「擴展」語句
- 9. Ruby擴展由FFI
- 10. Ruby:擴展自我
- 11. Rails - 擴展Ruby Gem
- 12. 用C++擴展Ruby?
- 13. 擴展擴展類型
- 14. 擴展擴展類Zend_Db_Table_Row_Abstract
- 15. Ruby擴展鏈接錯誤
- 16. 編譯Ruby的C++擴展
- 17. Ruby on Rails:擴展ActiveRecord :: Errors
- 18. 在Ruby中擴展對象
- 19. 擴展Ruby on Rails站點
- 20. Ruby on Rails的擴展?
- 21. Ruby:擴展實例變量
- 22. Ruby mixins:擴展幷包含
- 23. 如何編譯Ruby擴展
- 24. Laravel擴展類
- 25. php擴展類
- 26. 擴展MembershipUser類
- 27. PHP擴展類
- 28. 爲擴展類
- 29. 擴展IntentService類
- 30. 擴展類
難道你不能從超級通話的參數列表中完全刪除嗎? Super應該使用與當前方法相同的參數,除非你給它別的東西。但是,Class.new聽起來像大衛正在尋找的東西。 – Chuck 2009-08-29 04:52:16
你可以在一個正常的定義中,而不是在'define_method'中,它是一個'運行時錯誤:不支持define_method()定義的方法中的超級隱式參數傳遞。顯式指定所有參數。如果davidk01總是重新定義相同的方法,那麼正常的'def meth ... end'語法將起作用。 – rampion 2009-08-29 05:11:06