有没有办法在红宝石中重新定义[] = +

Cha*_*les 3 ruby metaprogramming redis

我正在尝试编写一个简单的DSL(针对Redis),我想定义[] + =我自己

我有

def []=(key,val)
  @redis.zadd(@name,val,key)
end
Run Code Online (Sandbox Code Playgroud)

我想定义

def []+=(key,val)
  @redis.zincrby(@name,val,key)
end
Run Code Online (Sandbox Code Playgroud)

但我的理解是Ruby提供了"[] + ="运算符自动赋予[] =

有没有办法克服这种行为显然我不想要这个,因为我不能,比方说,在管道模式下运行它

Mar*_*une 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
Run Code Online (Sandbox Code Playgroud)

这只是一个起点.你必须要比这更谨慎,例如通过检查键是相同的.在我的简单例子中,redis[:foo] = redis[:bar] + 1实际上相当于redis[:foo] += 1......

  • +1(因为它很有意思)但我通常建议不要采用这种方法......因为系统的可能*增加的复杂性(以及所需的知识)是不值得的. (2认同)