我想在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类对象扩展
- 3. Ruby:一个扩展模块的类
- 4. 扩展Ruby类(散)的新功能(recursive_merge)
- 5. Ruby - 类中的“扩展”语句
- 6. 用C++扩展Ruby?
- 7. Ruby扩展由FFI
- 8. Ruby:扩展自我
- 9. 扩展扩展类型
- 10. 扩展扩展类Zend_Db_Table_Row_Abstract
- 11. 编译Ruby的C++扩展
- 12. Ruby扩展链接错误
- 13. 扩展Ruby on Rails站点
- 14. 在Ruby中扩展对象
- 15. Ruby on Rails:扩展ActiveRecord :: Errors
- 16. php扩展类
- 17. php类扩展
- 18. 扩展CSS类
- 19. Javascript扩展类
- 20. 扩展PHP类
- 21. 扩展Java类
- 22. C++类扩展
- 23. PHP扩展类
- 24. 扩展Java类
- 25. 扩展ActiveResource类
- 26. 类和扩展
- 27. IBActions类扩展
- 28. 扩展PDO类
- 29. 扩展基类
- 30. 扩展PsCredential类
难道你不能从超级通话的参数列表中完全删除吗? 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