Ruby 可以定义一些泛型运算符吗?
Can Ruby define some generic operator?
我刚刚了解到 Ruby 的 "spaceship operator"、<=>
。
我觉得很有趣。 Ruby 可以定义我们自己的特殊运算符,例如 >=<
与 <=>
相反吗?
它可以应用于像 Java 模板这样的通用类型吗?
我该怎么做?
Ruby中有一组固定的运算符,其中一些是消息发送的语法糖,因此可以被覆盖。
您不能添加新的操作员。在Ruby中,固定的运算符集是语言语法的一部分,Ruby不允许Ruby代码改变语言的语法。如果你想添加一个新的运算符,你将不得不说服 matz 改变语言规范,你将不得不说服 Rubinius、JRuby、YARV、MagLev 和 MRuby 的开发者实施此更改。
可覆盖
这些脱糖到消息发送中,因此可以通过实现相应的方法来覆盖。
- 一元前缀
+foo
→ foo.+@()
,因此:def +@; end
-foo
→ foo.-@()
,因此:def -@; end
!foo
→ foo.!()
,因此:def !; end
~foo
→ foo.~()
,因此:def ~; end
- 二进制中缀
foo + bar
→ foo.+(bar)
,因此:def +(other) end
foo - bar
→ foo.-(bar)
,因此:def -(other) end
foo * bar
→ foo.*(bar)
,因此:def *(other) end
foo / bar
→ foo./(bar)
,因此:def /(other) end
foo % bar
→ foo.%(bar)
,因此:def %(other) end
foo ** bar
→ foo.**(bar)
,因此:def **(other) end
foo >> bar
→ foo.>>(bar)
,因此:def >>(other) end
foo << bar
→ foo.<<(bar)
,因此:def <<(other) end
foo & bar
→ foo.&(bar)
,因此:def &(other) end
foo ^ bar
→ foo.^(bar)
,因此:def ^(other) end
foo | bar
→ foo.|(bar)
,因此:def |(other) end
foo < bar
→ foo.<(bar)
,因此:def <(other) end
foo > bar
→ foo.>(bar)
,因此:def >(other) end
foo <= bar
→ foo.<=(bar)
,因此:def <=(other) end
foo >= bar
→ foo.>=(bar)
,因此:def >=(other) end
foo == bar
→ foo.==(bar)
,因此:def ==(other) end
foo === bar
→ foo.===(bar)
,因此:def ===(other) end
foo != bar
→ foo.!=(bar)
,因此:def !=(other) end
foo =~ bar
→ foo.=~(bar)
,因此:def =~(other) end
foo !~ bar
→ foo.!~(bar)
,因此:def !~(other) end
foo <=> bar
→ foo.<=>(bar)
,因此:def <=>(other) end
- 正进制"around-fix"
foo[bar, baz]
→ foo.[](bar, baz)
,因此:def [](a, b) end
foo[bar, baz] = quux
→ foo.[]=(bar, baz, quux)
,因此:def []=(a, b, c) end
foo.(bar, baz)
→ foo.call(bar, baz)
,因此:def call(a, b) end
不可覆盖
这些不会脱糖到消息发送中。
- 一元前缀
defined?
- 二进制中缀
foo && bar
foo and bar
foo || bar
foo or bar
foo = bar
- 复合赋值
foo ||= bar
foo &&= bar
有点可替代
您不能独立地覆盖这些,但它们(至少部分)转化为其他可以被覆盖的运算符。
- 一元前缀
not foo
→ foo.!()
,因此:def !; end
- 复合赋值
foo ω= bar
→ foo = foo ω bar
对于任何 ω ∉ { ||
, &&
}
我刚刚了解到 Ruby 的 "spaceship operator"、<=>
。
我觉得很有趣。 Ruby 可以定义我们自己的特殊运算符,例如 >=<
与 <=>
相反吗?
它可以应用于像 Java 模板这样的通用类型吗?
我该怎么做?
Ruby中有一组固定的运算符,其中一些是消息发送的语法糖,因此可以被覆盖。
您不能添加新的操作员。在Ruby中,固定的运算符集是语言语法的一部分,Ruby不允许Ruby代码改变语言的语法。如果你想添加一个新的运算符,你将不得不说服 matz 改变语言规范,你将不得不说服 Rubinius、JRuby、YARV、MagLev 和 MRuby 的开发者实施此更改。
可覆盖
这些脱糖到消息发送中,因此可以通过实现相应的方法来覆盖。
- 一元前缀
+foo
→foo.+@()
,因此:def +@; end
-foo
→foo.-@()
,因此:def -@; end
!foo
→foo.!()
,因此:def !; end
~foo
→foo.~()
,因此:def ~; end
- 二进制中缀
foo + bar
→foo.+(bar)
,因此:def +(other) end
foo - bar
→foo.-(bar)
,因此:def -(other) end
foo * bar
→foo.*(bar)
,因此:def *(other) end
foo / bar
→foo./(bar)
,因此:def /(other) end
foo % bar
→foo.%(bar)
,因此:def %(other) end
foo ** bar
→foo.**(bar)
,因此:def **(other) end
foo >> bar
→foo.>>(bar)
,因此:def >>(other) end
foo << bar
→foo.<<(bar)
,因此:def <<(other) end
foo & bar
→foo.&(bar)
,因此:def &(other) end
foo ^ bar
→foo.^(bar)
,因此:def ^(other) end
foo | bar
→foo.|(bar)
,因此:def |(other) end
foo < bar
→foo.<(bar)
,因此:def <(other) end
foo > bar
→foo.>(bar)
,因此:def >(other) end
foo <= bar
→foo.<=(bar)
,因此:def <=(other) end
foo >= bar
→foo.>=(bar)
,因此:def >=(other) end
foo == bar
→foo.==(bar)
,因此:def ==(other) end
foo === bar
→foo.===(bar)
,因此:def ===(other) end
foo != bar
→foo.!=(bar)
,因此:def !=(other) end
foo =~ bar
→foo.=~(bar)
,因此:def =~(other) end
foo !~ bar
→foo.!~(bar)
,因此:def !~(other) end
foo <=> bar
→foo.<=>(bar)
,因此:def <=>(other) end
- 正进制"around-fix"
foo[bar, baz]
→foo.[](bar, baz)
,因此:def [](a, b) end
foo[bar, baz] = quux
→foo.[]=(bar, baz, quux)
,因此:def []=(a, b, c) end
foo.(bar, baz)
→foo.call(bar, baz)
,因此:def call(a, b) end
不可覆盖
这些不会脱糖到消息发送中。
- 一元前缀
defined?
- 二进制中缀
foo && bar
foo and bar
foo || bar
foo or bar
foo = bar
- 复合赋值
foo ||= bar
foo &&= bar
有点可替代
您不能独立地覆盖这些,但它们(至少部分)转化为其他可以被覆盖的运算符。
- 一元前缀
not foo
→foo.!()
,因此:def !; end
- 复合赋值
foo ω= bar
→foo = foo ω bar
对于任何 ω ∉ {||
,&&
}