开发者

How to overload operators with a method name in Ruby?

Let's say I have a class named Foo:

Class Foo
  def method=(params)
    puts params
  end
  def +(params)
    puts params
  end
  def method+(params)
    puts params
  end
end

In the above, after initializing the class to a new object, which I'll call myobj (myobj = Foo.new), calling myobj.method = "string" and myobj + "strin开发者_Go百科g" will both print that string. However, a syntax error is thrown when I try to define method+. I want to be able to call myobj.method + "string". Can anyone help?


This is not actually a case of what characters can appear in method names ('+' is technically allowed), but rather the parsing and precedence rules of the language.

The reason def method= works is that it is Ruby's special syntax for property accessors. When you define method=, semantically you are saying that the foo has an accessible @method instance variable, or at least acts like it.

It is a special case, and all other operators bind less strongly than the . method call. In foo.method + "string", method is called on foo and then +("string") is called on the result.


Ruby won't let you define a whatever+ method like it will with whatever= - if you need the behaviour you're describing, you'll need to make a "method" object, define the + operator for it, and return it from a call to Foo.method:

class Method
    def + (params)
        puts params
    end

    def = (params)
        puts params
    end
end

class Foo
    def + (params)
        puts params
    end

    def method
        return Method.new
    end
end

I've moved the = operator into the method object as well, but that one doesn't really matter (since you can def method=) - it just seemed logical. And if you need to put this into practice, you should probably make Method a member class of Foo:

class Foo
    class Method
    end
end

so you keep your namespaces clean. You can always use Foo::Method to get at that class when you need it.

Hope this helps!


A method is not an object, and operators are attributes of objects, not methods. This won't work.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜