Spaceship Operator (<=>) • Basic operator for comparing the receiver against another object • Also known as UFO operator (least in Japan) • Classes mix-ins Comparable must implement <=> DMBTT 4J[F.BUUFST JODMVEF $PNQBSBCMF EFG JOJUJBMJ[F TUS !TUS TUS FOE
EFG PUIFS TUS TJ[F PUIFS TUS TJ[F FOE FOE
Implementation of <=> It should return •Positive number if self is greater than other •Zero if self is equal to other •Negative number if self is less than other DMBTT 'PP ǘ EFG PUIFS SFUVSO JG TJ[F PUIFS TJ[F SFUVSO JG TJ[F PUIFS TJ[F SFUVSO JG TJ[F PUIFS TJ[F FOE FOE GPP GPP USVF GBMTF
A tip for using <=> DBTF GPP CBS XIFO QVUT GPP JT FRVBM UP CBS XIFO QVUT GPP JT HSFBUFS UIBO CBS FMTF QVUT GPP JT MFTT UIBO CBS FOE • You can write like this using its implementation • Looks pretty convenient, doesn t it?
A tip for using <=> 0？1？ Greater if positive? DBTF GPP CBS Or less if postive? XIFO Or positive if positive? QVUT GPP JT FRVBM UP CBS WTF? XIFO QVUT GPP JT HSFBUFS UIBO CBS FMTF QVUT GPP JT MFTT UIBO CBS FOE • You can write like this using its implementation • Looks pretty convenient, doesn t it?
So I always do the following steps when I want to use comparison operators with my classes 1. Include the module in a class 2. Start writing `def <=>(other); end` 3. be anguished trying to remind me to if greater/less must return positive/negative number 4. Googling for a while 5. It does not work… 6. Uh oh I include Enumerable instead of Comparable
So I think Implementation of <=> exceptionally lacks descriptive power in Ruby world almost seems like magic numbers
It reminds me of something like JOU DPNQBSF@JOU DPOTU WPJE B DPOTU WPJE C \ SFUVSO JOU B JOU C ^ JOU NBJO \ JOU EBUB<> \ ^ RTPSU EBUB TJ[FPG JOU DPNQBSF@JOU ^ • Old school C-ish ﬂavor • Java (compareTo) / .NET (CompareTo)
(I am sure you can use if…elsif… though) I wish I could write like DBTF GPP CBS XIFO &2 QVUT GPP JT FRVBM UP CBS XIFO (5 QVUT GPP JT HSFBUFS UIBO CBS FMTF QVUT GPP JT MFTT UIBO CBS FOE • It would be easier to know the codes intension
What if you simply use constants NPEVMF 0SEFSJOH (5 'MPBU */'*/*5: -5 'MPBU */'*/*5: &2 FOE DBTF GPP CBS XIFO 0SEFSJOH &2 QVUT GPP JT FRVBM UP CBS XIFO 0SEFSJOH (5 QVUT GPP JT HSFBUFS UIBO CBS XIFO 0SEFSJOH -5 QVUT GPP JT MFTT UIBO CBS FOE • Range using INFINITY would work with case expression
What if these constants are available in global namespace… EFG PUIFS JG TJ[F PUIFS TJ[F 0SEFSJOH (5 FMTJG TJ[F PUIFS TJ[F 0SEFSJOH &2 FMTF 0SEFSJOH -5 FOE FOE • It does not work because of their types • Maybe it has some overhead
I am sure implementation requirement of <=> lets you to write like EFG PUIFS TJ[F PUIFS TJ[F FOE I love this as it is clean and concise enough (as long as you understand its requirement correctly)
Conclusion (?) •In almost all cases the implementation that <=> returns -n/0/n is enough and also has advantage •More descriptive options would be very welcome especially for newbies •I don t have any good ideas yet 😞 (considering if singleton objects like nil/true/false work)