5 ms·
The ordering operators
- samatman 5y ago<=> has some of the semantics of Fortran's "arithmetic" IF statement. This can be useful, as the Fine Article shows, in sorts and searches, I've rolled it by hand a few times for tests like "is this offset in the line we're examining".
- omoikane 5y ago<=> and cmp also have the benefit that fewer comparisons are done. It might not be that big a deal for Perl scalars, but for C++, an overloaded operator< that does something like this: return left.a != right.a ? left.a < right.a : left.b < right.b; That might result in exponential number of compare operations if those nested comparisons are also overloaded, whereas with <=> (as of C++20), the number of compare operations can be made to be linear: return left.a <=> right.a < 0 || left.b <=> right.b < 0;
- omoikane 5y agoSorry, that should have been: return !(left.a <=> right.a >= 0 && left.b <=> right.b >= 0);
- mcphage 5y agoCan you use <=> on arrays in Perl? In ruby that would be [$maj, $min, $rel] <=> [3, 6, 8]
- smueller1234 5y agoAt least in Perl 5 (which TFA uses), you can not. Or certainly not expect a useful result. https://perldoc.perl.org/perlop#Relational-Operators https://perldoc.perl.org/perlop#Relational-Operators
- toast0 5y agoIt says a numerical comparison, so it will compare only the length of the arrays.
- ilyash 5y agoFor comparison, in Next Generation Shell, the above would be solved as follows: version_ok = version.split(".").map(Int) >= [3, 6, 8]
- tedmiston 5y agoNGS looks interesting as a Bash alternative. https://github.com/ngs-lang/ngs https://github.com/ngs-lang/ngs
- ilyash 5y agoThank you! For scripting, it is significantly better than bash (at least for most of the cases that I have). The interactive part is not implemented yet but it is planned to be quite different from the dominant decades old approach. The plan is at https://github.com/ngs-lang/ngs/wiki/UI-Design https://github.com/ngs-lang/ngs/wiki/UI-Design
- tialaramex 5y agoInteresting, why is there a separate operator for strings? Are there scenarios when either operator (cmp or <=>) works, but they have different behaviour?
- bewuethr 5y agoYes, when you compare numbers lexically, "cmp" will say that 2 sorts after 10, and "<=>" will say it sorts before: perl -e 'printf "%d %d\n", 2 <=> 10, 2 cmp 10' prints -1 1
- darrenf 5y ago> Are there scenarios when either operator (cmp or <=>) works, but they have different behaviour? It being Perl, you can basically throw anything at either operator if you like. It's trivial to find examples where the answers are different: perl -wlE 'say "a" <=> "b"; say "a" cmp "b";' Argument "b" isn't numeric in numeric comparison (<=>) at -e line 1. Argument "a" isn't numeric in numeric comparison (<=>) at -e line 1. 0 -1
- adrianmonk 5y agoPerl doesn't have a way to say "this value is a number" or "this value is a string". Instead, the two are effectively the same type (which Perl calls a scalar value), and you use different operators to treat them like strings or numbers as desired. So, for example, you can do something like this: # declare $a and initialize it with a literal # numerical value of 3. my $a = 3; # switch gears and treat it like a string # instead of a number by appending an "X". $a .= "X"; # output a line that says "3X". print "$a\n"; Or like this: # declare $b and initialize it with a literal # string value of "l33t". my $b = "l33t"; # do a regex substitution (string operation) # to remove letters. New string will be "33". $b =~ s/[a-z]//g; # multiply string "33" times 3. $b *= (1 + 1 + 1); # output a line that says "99". print "$b\n"; So, if you have an array of scalar values like "123" and "5", Perl doesn't know whether to sort these as numbers (5 goes first) or as strings ("123" goes first) because the value isn't necessarily a string or a number.
- 5y ago