2012-02-14 99 views
14

我有一個自定義類,希望能夠覆蓋賦值運算符。 這裏是一個例子:具有多個參數的Setter方法(賦值)

class MyArray < Array 
    attr_accessor :direction 
    def initialize 
    @direction = :forward 
    end 
end 
class History 
    def initialize 
    @strategy = MyArray.new 
    end 
    def strategy=(strategy, direction = :forward) 
    @strategy << strategy 
    @strategy.direction = direction 
    end 
end 

這目前不能按預期工作。在使用時的

h = History.new 
h.strategy = :mystrategy, :backward 

[:mystrategy, :backward]獲取分配給該策略和可變的方向變量保持:forward
重要的是我希望能夠爲方向參數分配一個標準值。

任何線索,使這項工作受到高度讚賞。

回答

14

由於的後綴名爲=方法的語法糖,實際上你可以將多個參數傳遞給方法的唯一方法是繞過語法糖和使用send ...

h.send(:strategy=, :mystrategy, :backward) 

...其中情況下,你可能也只是用普通方法具有更好的名稱:

h.set_strategy :mystrategy, :backward 

但是,您可以重寫你的方法來自動取消數組,如果你的價值觀知道陣列永遠不會對該參數合法:

def strategy=(value) 
    if value.is_a?(Array) 
    @strategy << value.first 
    @strategy.direction = value.last 
    else 
    @strategy = value 
    end 
end 

但是,這看起來像一個嚴重的黑客攻擊。如果您需要它們,我會使用帶有多個參數的非分配方法名稱。


另外一個建議:如果只是方向:forward:backward怎麼樣:

def forward_strategy=(name) 
    @strategy << name 
    @strategy.direction = :forward 
end 

def reverse_strategy=(name) 
    @strategy << name 
    @strategy.direction = :backward 
end 
+0

編輯爲替代實現添加另一個建議。 – Phrogz 2012-02-14 17:05:12

+0

我喜歡你檢查數值是否爲Array的建議。你說它是一個嚴重的黑客攻擊。哪裏會使用這個原因麻煩? – FlyingFoX 2012-02-14 17:23:25

+1

@FlyingFoX這是一個「粗暴的黑客」,因爲它不是慣用的,不是自我記錄的,並且通常不適用(在某些人可能想要傳遞數組作爲第一個參數的情況下)。 – Phrogz 2012-02-14 17:59:26

2

問題是

def strategy=(strategy, direction = :forward) 
    @strategy = strategy 
    @strategy.direction = direction 
end 

當您設置

h.strategy = :mystrategy, :backward 

你實際上覆蓋了原來的@strategy實例。在該呼叫之後,@strategySymbol的實例,而不是。

你想做什麼?替換對象還是更新它?

+0

哦,好像我搞砸了這個方法。它應該是'@策略'戰略'。 – FlyingFoX 2012-02-14 16:55:21

+0

哦;所以一個策略沒有方向,而是你有一個策略列表和一個當前的方向? – Phrogz 2012-02-14 16:59:29