[HN Gopher] The ordering operators
___________________________________________________________________
The ordering operators
Author : Amorymeltzer
Score : 27 points
Date : 2022-04-07 09:52 UTC (2 days ago)
(HTM) web link (blogs.perl.org)
(TXT) w3m dump (blogs.perl.org)
| tialaramex wrote:
| Interesting, why is there a separate operator for strings?
|
| Are there scenarios when either operator (cmp or <=>) works, but
| they have different behaviour?
| adrianmonk wrote:
| Perl 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.
| heresie-dabord wrote:
| > Perl doesn't have a way to say "this value is a number" or
| "this value is a string".
|
| use Scalar::Util qw(looks_like_number);
|
| #example
|
| if(looks_like_number($value)) { say "$value is a number"; }
| a1369209993 wrote:
| my @chips = ("74HC08","8085AH","555","7C199-15");
| use_value($_) foreach @chips;
|
| 555 is a number; "555" is not a number.
| jwilk wrote:
| But looks_like_number("42") is still true.
|
| 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"
| bewuethr wrote:
| Yes, 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 wrote:
| > _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
| ilyash wrote:
| For comparison, in Next Generation Shell, the above would be
| solved as follows: version_ok =
| version.split(".").map(Int) >= [3, 6, 8]
| tedmiston wrote:
| NGS looks interesting as a Bash alternative.
|
| https://github.com/ngs-lang/ngs
| mcphage wrote:
| Can you use <=> on arrays in Perl? In ruby that would be [$maj,
| $min, $rel] <=> [3, 6, 8]
| smueller1234 wrote:
| At least in Perl 5 (which TFA uses), you can not. Or certainly
| not expect a useful result.
|
| https://perldoc.perl.org/perlop#Relational-Operators
| toast0 wrote:
| It says a numerical comparison, so it will compare only the
| length of the arrays.
| samatman wrote:
| <=> 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 wrote:
| <=> 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;
___________________________________________________________________
(page generated 2022-04-09 23:02 UTC)