The ordering operators
blogs.perl.org
blogs.perl.org
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".
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; return !(left.a <=> right.a >= 0 && left.b <=> right.b >= 0); version_ok = version.split(".").map(Int) >= [3, 6, 8]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
Are there scenarios when either operator (cmp or <=>) works, but they have different behaviour?
perl -e 'printf "%d %d\n", 2 <=> 10, 2 cmp 10'
prints -1 1It 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
-1Instead, 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.use Scalar::Util qw(looks_like_number);
#example
if(looks_like_number($value)) { say "$value is a number"; }
my @chips = ("74HC08","8085AH","555","7C199-15");
use_value($_) foreach @chips;
555 is a number; "555" is not a number.OTOH, JSON::PP can tell the difference between string and number:
$ perl -MJSON::PP -E 'say JSON::PP::encode_json(42);'
42
$ perl -MJSON::PP -E 'say JSON::PP::encode_json("42");'
"42""JSON recognises JSON".
This isn't really any different than JavaScript or similar languages that perform automatic type coercion. Internally scalars are differentiated. When writing Perl XS (the C extension interface), scalars are clearly differentiated into integers, doubles, strings, references (Perl's equivalent of pointers), and several other internal types. In a sense, a Perl scalar is the same as a "scalar" in many other languages (whether strongly or weakly, statically or dynamically typed), where you have two basic types--scalar and compound types. In C an integer, floating point, and pointer are all scalar values, as distinguished from an array, struct, or union.
So when you do `my $a = 3;`, `$a` at that point is definitely an integer type. However, it can be coerced (both conceptually and literally--in Perl objects are mutable and can have both their value and type changed in-place) into a string according to Perl's extremely complex DWIM type coercion rules.
"1" + "1" is "11" in JavaScript. In Perl, it's 2. There's also no JS-like `typeof` operator in Perl. The types you mention in Perl XS are just an implementation detail from the perspective of the language itself. "1" and 1 are exactly the same value, not different values that can be coerced into each other.