I just learned about Ruby's "spaceship operator", <=>.
I find it interesting. Can Ruby define our own special operators like >=< for opposite of <=>?
Could it be applied to generic types like Java templates?
How do I do it?
I just learned about Ruby's "spaceship operator", <=>.
I find it interesting. Can Ruby define our own special operators like >=< for opposite of <=>?
Could it be applied to generic types like Java templates?
How do I do it?
There is a fixed set of operators in Ruby, some of which are syntactic sugar for message sends and can thus be overridden.
You can't add new operators. In Ruby, the fixed set of operators is part of the language syntax, and Ruby doesn't allow Ruby code to change the syntax of the language. If you want to add a new operator, you will have to convince matz to change the language specification, and you will have to convince the developers of Rubinius, JRuby, YARV, MagLev, and MRuby to implement this change.
These desugar into message sends and thus can be overridden by implementing the corresponding methods.
+foo → foo.+@(), ergo: def +@; end-foo → foo.-@(), ergo: def -@; end!foo → foo.!(), ergo: def !; end~foo → foo.~(), ergo: def ~; endfoo + bar → foo.+(bar), ergo: def +(other) endfoo - bar → foo.-(bar), ergo: def -(other) endfoo * bar → foo.*(bar), ergo: def *(other) endfoo / bar → foo./(bar), ergo: def /(other) endfoo % bar → foo.%(bar), ergo: def %(other) endfoo ** bar → foo.**(bar), ergo: def **(other) endfoo >> bar → foo.>>(bar), ergo: def >>(other) endfoo << bar → foo.<<(bar), ergo: def <<(other) endfoo & bar → foo.&(bar), ergo: def &(other) endfoo ^ bar → foo.^(bar), ergo: def ^(other) endfoo | bar → foo.|(bar), ergo: def |(other) endfoo < bar → foo.<(bar), ergo: def <(other) endfoo > bar → foo.>(bar), ergo: def >(other) endfoo <= bar → foo.<=(bar), ergo: def <=(other) endfoo >= bar → foo.>=(bar), ergo: def >=(other) endfoo == bar → foo.==(bar), ergo: def ==(other) endfoo === bar → foo.===(bar), ergo: def ===(other) endfoo != bar → foo.!=(bar), ergo: def !=(other) endfoo =~ bar → foo.=~(bar), ergo: def =~(other) endfoo !~ bar → foo.!~(bar), ergo: def !~(other) endfoo <=> bar → foo.<=>(bar), ergo: def <=>(other) endfoo[bar, baz] → foo.[](bar, baz), ergo: def [](a, b) endfoo[bar, baz] = quux → foo.[]=(bar, baz, quux), ergo: def []=(a, b, c) endfoo.(bar, baz) → foo.call(bar, baz), ergo: def call(a, b) endThese don't desugar into message sends.
defined?foo && barfoo and barfoo || barfoo or barfoo = barfoo ||= barfoo &&= barYou can't override these independently, but they (at least partially) translate into other operators that can be overridden.
not foo → foo.!(), ergo: def !; endfoo ω= bar → foo = foo ω bar for any ω ∉ { ||, && }