【问题标题】:How to overload operators with a method name in Ruby?如何在 Ruby 中使用方法名重载运算符?
【发布时间】:2011-04-04 22:29:36
【问题描述】:

假设我有一个名为 Foo 的类:

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

在上面,将类初始化为一个新对象后,我将其称为 myobj (myobj = Foo.new),调用 myobj.method = "string" 和 myobj + "string" 都会打印该字符串。但是,当我尝试定义 method+ 时会引发语法错误。我希望能够调用 myobj.method +“字符串”。有人可以帮忙吗?

【问题讨论】:

    标签: ruby


    【解决方案1】:

    这实际上不是什么字符可以出现在方法名称中的情况(“+”在技术上是允许的),而是语言的解析和优先规则。

    def method= 起作用的原因是它是 Ruby 用于属性访问器的特殊语法。当你定义 method= 时,语义上你是在说 foo 有一个可访问的 @method 实例变量,或者至少表现得像它。

    这是一种特殊情况,所有其他运算符的绑定不如. 方法调用强。在foo.method + "string" 中,methodfoo 上调用,然后在结果上调用+("string")

    【讨论】:

      【解决方案2】:

      Ruby 不会让您像使用 whatever= 那样定义 whatever+ 方法 - 如果您需要您描述的行为,您需要创建一个“方法”对象,定义 +运算符,并将其从对 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
      

      我也将= 运算符移到了方法对象中,但这并不重要(因为你可以def method=)——这看起来很合乎逻辑。如果你需要把它付诸实践,你可能应该让 Method 成为 Foo 的成员类:

      class Foo
          class Method
          end
      end
      

      所以你保持你的命名空间干净。您可以随时使用Foo::Method 在需要时参加该课程。

      希望这会有所帮助!

      【讨论】:

        【解决方案3】:

        方法不是对象,运算符是对象的属性,而不是方法。这行不通。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-12-21
          • 1970-01-01
          • 1970-01-01
          • 2017-12-02
          • 1970-01-01
          • 2013-04-29
          • 1970-01-01
          • 2015-04-12
          相关资源
          最近更新 更多