Ruby可以定义一些通用运算符吗?

时间:2015-11-10 00:16:07

标签: ruby generic-programming

我刚刚了解了Ruby&#34;太空飞船运营商&#34;,<=>

我发现它很有趣。 Ruby可以定义我们自己的特殊运算符,例如>=<的对象<=>吗?

是否可以应用于Java模板等泛型类型?

我该怎么做?

1 个答案:

答案 0 :(得分:3)

Ruby中有一组固定的运算符,其中一些是用于消息发送的语法糖,因此可以被覆盖。

您无法添加新运算符。在Ruby中,固定的运算符集是语言语法的一部分,Ruby不允许Ruby代码更改语言的语法。如果你想添加一个新的运算符,你必须说服matz改变语言规范,你必须说服Rubinius,JRuby,YARV,MagLev和MRuby的开发人员来实现这个改变。

可重写

这些desugar into message发送,因此可以通过实现相应的方法来覆盖。

  • 一元前缀
    • +foofoo.+@(),ergo:def +@; end
    • -foofoo.-@(),ergo:def -@; end
    • !foofoo.!(),ergo:def !; end
    • ~foofoo.~(),ergo:def ~; end
  • 二进制中缀
    • foo + barfoo.+(bar),ergo:def +(other) end
    • foo - barfoo.-(bar),ergo:def -(other) end
    • foo * barfoo.*(bar),ergo:def *(other) end
    • foo / barfoo./(bar),ergo:def /(other) end
    • foo % barfoo.%(bar),ergo:def %(other) end
    • foo ** barfoo.**(bar),ergo:def **(other) end
    • foo >> barfoo.>>(bar),ergo:def >>(other) end
    • foo << barfoo.<<(bar),ergo:def <<(other) end
    • foo & barfoo.&(bar),ergo:def &(other) end
    • foo ^ barfoo.^(bar),ergo:def ^(other) end
    • foo | barfoo.|(bar),ergo:def |(other) end
    • foo < barfoo.<(bar),ergo:def <(other) end
    • foo > barfoo.>(bar),ergo:def >(other) end
    • foo <= barfoo.<=(bar),ergo:def <=(other) end
    • foo >= barfoo.>=(bar),ergo:def >=(other) end
    • foo == barfoo.==(bar),ergo:def ==(other) end
    • foo === barfoo.===(bar),ergo:def ===(other) end
    • foo != barfoo.!=(bar),ergo:def !=(other) end
    • foo =~ barfoo.=~(bar),ergo:def =~(other) end
    • foo !~ barfoo.!~(bar),ergo:def !~(other) end
    • foo <=> barfoo.<=>(bar),ergo:def <=>(other) end
  • n-ary“around-fix”
    • foo[bar, baz]foo.[](bar, baz),ergo:def [](a, b) end
    • foo[bar, baz] = quuxfoo.[]=(bar, baz, quux),ergo:def []=(a, b, c) end
    • foo.(bar, baz)foo.call(bar, baz),ergo:def call(a, b) end

非重写的

这些不会发送到消息发送中。

  • 一元前缀
    • defined?
  • 二进制中缀
    • foo && bar
    • foo and bar
    • foo || bar
    • foo or bar
    • foo = bar
  • 复合作业
    • foo ||= bar
    • foo &&= bar

可覆盖的排序

您不能单独覆盖这些内容,但它们(至少部分地)会转换为可以被覆盖的其他运算符。

  • 一元前缀
    • not foofoo.!(),ergo:def !; end
  • 复合作业
    • foo ω= barfoo = foo ω bar任意ω∉{||&&}