2009-08-29 162 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] 

我不喜歡的東西,以前通過保存我到一個文本文件中所作的更改,並從頭再來當讀取該文件該程序重新啓動或重新加載它的設置。