2013-06-24 17 views
3

我有服務api。我的Base類有一些方法,我有具體的實現繼承這個類並實現它的方法。我有幾個Base類的實現者。使用一些機制來修剪方法的返回值

我有大約20個方法,我想所有的這些方法修剪的返回值。但是我不願意添加一些代碼來修改20個方法中的每一個的返回值。我正在尋找更好的方法來做到這一點。

不過,我覺得我在這裏找到:

http://cheind.blogspot.com/2008/12/method-hooks-in-ruby.html

但這種方法只適用於我Base類,而不是對誰實施Base類的類。如何將它應用於我的所有實現類?

+1

你不能讓具有裝飾包裝方法的中間階段?你可以在這個功能上包含一個'module'來做什麼? – tadman

回答

1

我認爲實施Presenter(a.k.a Exhibit)模式是有意義的。基本概念是用代理添加一層表示邏輯來包裝對象。你可以找到更多關於這個模式在這裏:

前往一些實際的代碼,你可以想像有這樣一個類:

class Test 
    def baked 
    " baked" 
    end 

    def beans 
    " beans " 
    end 

    def food_methods 
    [:baked, :beans] 
    end 
end 

test = Test.new 
p "#{test.baked} #{test.beans}" 

Ruby標準庫提供了一個名爲SimpleDelegator的整潔實用程序,它提供了我們所需的大部分功能。因此,我們只需要dinamically定義一些方法和包裝了原始的對象在新呈現的對象:

require 'delegate' 

class TestPresenter < SimpleDelegator 
    Test.new.food_methods.each do |method| 
    define_method(method) do |*args| 
     __getobj__.send(method, *args).strip 
    end 
    end 
end 

presenter = TestPresenter.new(test) 
p "#{presenter.baked} #{presenter.beans}" 
0

警告:該解決方案是不是「乾淨」爲@菊柳的,它可能ISN效率最高,但在您的工作流程中實施起來更短,更容易。您也可能想限制要重新定義的方法並構建更好的錯誤處理。

裏面你Base類,你可以這樣做:

(Base.instance_methods - Class.instance_methods).each do |method| 
    alias_method "#{method}_backup", method  
    class_eval %Q{  
    def #{method}(*args) 
     #{method}_backup(*args).strip rescue #{method}_backup(*args) 
    end 
    } 
end