in reply to "2" | "8" = ":" and 2|8=10

You're right. Bitwise operators are the only place where there's a difference between strings and numbers. BTW This difference does not fit into the philosophy of Perl, where you should not be able to distinguish between strings and numbers, so this is actually a language design flaw.

You could detect if a scalar is a string or a number, without resorting to XS, by making use of this different behavior. If you use bitwise XOR (^) and XOR a scalar with itself, you'll get the value 0 if it was a number, and a string of null bytes ("\0") with the original string length of the argument, if it was a string. Yes, even if the number doesn't fit into an integer, like 1E99.

I think this will work:

sub is_number { my $arg = shift; return defined $arg && !ref $arg && ($arg^$arg) eq '0'; }
BTW dual-vars, like !1, are treated as a number.

Replies are listed 'Best First'.
Re^2: "2" | "8" = ":" and 2|8=10
by moritz (Cardinal) on Nov 04, 2011 at 12:42 UTC
    BTW This difference does not fit into the philosophy of Perl, where you should not be able to distinguish between strings and numbers, so this is actually a language design flaw.

    Agreed. Perl always had the philosophy that the operators determine the operation, not the type of the operands. Perl 6 solves this by adding type modifiers for the bitwise operators:

    $a +| $b; # Integer bitwise OR $a ~| $b; # String bitwise OR $a ?| $b # logical OR

    It makes the bitwise operators look a bit more ugly, but I don't really mind because I don't use them very often. This change has the additional benefit of freeing up the characters that perl 5 uses for bitwise operators.

    (Note that || as a logical OR still exists; the difference is that || returns the first true value, whereas ?| always returns a Bool).

Re^2: "2" | "8" = ":" and 2|8=10
by JavaFan (Canon) on Nov 04, 2011 at 12:39 UTC
    Bitwise operators are the only place where there's a difference between strings and numbers.
    No. It matters for post-increment as well.
    BTW This difference does not fit into the philosophy of Perl, where you should not be able to distinguish between strings and numbers, so this is actually a language design flaw.
    It's a deliberate decision, and well worth the offset. It allows you to use bitfields that aren't restricted to 32 (or 64) bits.
      Bitwise operators are the only place where there's a difference between strings and numbers.
      No. It matters for post-increment as well.
      I think you're wrong there. Postincrement only works different for strings if they start with a letter. For strings like "199" it makes no difference: you just get 200. And other strings apparently are converted to a number first, as $x = "2A"; $x++ produces 3.
      It's a deliberate decision, and well worth the offset. It allows you to use bitfields that aren't restricted to 32 (or 64) bits.
      Yes, I don't question the functionality, that is useful. But the typical Perl thing to do would have been to provide different operators for strings and for numbers. Just as with = vs eq and + vs ..
        I think you're wrong there. Postincrement only works different for strings if they start with a letter. For strings like "199" it makes no difference: you just get 200. And other strings apparently are converted to a number first, as $x = "2A"; $x++ produces 3.
        $ perl -E '$x = $y = "A3"; $y + 0; $x++; $y++; say "$x $y"' A4 1 $
        The difference is, $y has an integer (as well as a string value), where $x doesn't. And hence, the post-increment value differs.