2012-06-15 67 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

我同意与操作员混淆是不好的。它可以使调试和维护非常困难。 –