2009-08-29 106 views
1

我想在ruby中编写一个方法,它接受某个方法的类并通过添加方法或更改现有方法的工作方式来修改其行为。我想以不修改基类的方式做到这一点,所以基本上我想要一个函数,它接受一个类并返回一个新的修改后的类,而不会损害初始类。我很确定这是可能的,但我不确定从哪里开始。ruby​​类扩展

回答

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|(捕获块参数中的块)。

+0

难道你不能从超级通话的参数列表中完全删除吗? Super应该使用与当前方法相同的参数,除非你给它别的东西。但是,Class.new听起来像大卫正在寻找的东西。 – Chuck 2009-08-29 04:52:16

+0

你可以在一个正常的定义中,而不是在'define_method'中,它是一个'运行时错误:不支持define_method()定义的方法中的超级隐式参数传递。显式指定所有参数。如果davidk01总是重新定义相同的方法,那么正常的'def meth ... end'语法将起作用。 – rampion 2009-08-29 05:11:06

1

我建议使用inheritancea 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] 

我不喜欢的东西,以前通过保存我到一个文本文件中所作的更改,并从头再来当读取该文件该程序重新启动或重新加载它的设置。