2012-06-15 106 views
3

我試圖寫一個簡單的DSL(對Redis的),我想定義[] + =自己有沒有一種方法來重新定義[] = +紅寶石

def []=(key,val) 
    @redis.zadd(@name,val,key) 
end 

,我想定義

def []+=(key,val) 
    @redis.zincrby(@name,val,key) 
end 

但我的理解是,Ruby提供的 「[] + =」 操作符automaticallygiven [] =

有沒有辦法來克服這種行爲 很明顯,我不想這樣做,因爲我不能說,在流水線模式下運行這個

回答

2

沒有。 x[y] += z擴展到準確x[y] = x[y] + z

class << (object = Object.new) 
    def [](key) 
    puts "[#{key.inspect}]" 
    key 
    end 

    def []=(key, value) 
    puts "[#{key.inspect}] = #{value.inspect}" 
    value 
    end 
end 

# These are all equivalent 
object['See?'] += " It's impossible." 
object['See?'] = object['See?'] + " It's impossible." 
object.[]=('See?', object.[]('See?').+(" It's impossible.")) 

# They all produce the same output: 
# ["See?"] 
# ["See?"] = "See? It's impossible." 
# => "See? It's impossible." 

您必須創建一個單獨的方法。

+2

雖然結論是正確的,但此代碼*並不顯示*,這是不可能的。也就是說,*不排除特殊的[] + ='操作符語法或'+ ='的綁定規則。爲了「證明」這一點,我們必須證明在適用的Ruby規範中沒有定義這樣的「特殊」操作符/綁定。 (祝你找到正式的Ruby規範!: - /) – 2012-06-15 22:13:11

+2

@pst:ISO規範在不久前正式獲得批准。 –

+1

@pst,看到Ruby語言將參考實現放棄爲[國際標準](http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=59579)真是太棒了。我當然想在我的答案中提到它;如此多的C語言問題已經被優雅地回答了。不幸的是,我沒有副本。 :) –

6

不,<operator>=不能在Ruby中重新定義。

你可以嘗試變得非常花哨,並將你的返回值包裝到委託給實際值的類中。這樣,他們表現得像實際價值,但你可以玩技巧,例如+

這裏有一個簡單的例子:

require 'delegate' 
module Redis 
    class Set 
    class Value < SimpleDelegator 
     def +(val) 
     Increment.new(self, val) 
     end 
    end 

    class Increment < SimpleDelegator 
     attr_reader :increment 
     def initialize(source, increment) 
     super(source.__getobj__ + increment) 
     @increment = increment 
     end 
    end 

    def [](key) 
     Value.new(@redis.not_sure_what(@name, key)) 
    end 

    def []=(key,val) 
     if val.is_a?(Increment) 
     @redis.zincrby(@name,val.increment,key) 
     else 
     @redis.zadd(@name,val,key) 
     end 
    end 
    end 
end 

這僅僅是一個起點。您必須比這更小心,例如通過檢查密鑰是否相同。在我簡單化的例子中,redis[:foo] = redis[:bar] + 1實際上相當於redis[:foo] += 1 ...

+2

+1(因爲它很有趣),但我通常會建議不要這樣做......因爲增加的系統複雜性(以及所需的知識)可能*不值得。 – 2012-06-15 22:49:18

+0

我同意與操作員混淆是不好的。它可以使調試和維護非常困難。 –