How to tell apart numeric scalars and string scalars in Perl?

前端 未结 9 1431
一生所求
一生所求 2020-12-16 12:31

Perl usually converts numeric to string values and vice versa transparently. Yet there must be something which allows e.g. Data::Dumper to discriminate between

9条回答
  •  [愿得一人]
    2020-12-16 12:46

    A scalar has a number of different fields. When using Perl 5.8 or higher, Data::Dumper inspects if there's anything in the IV (integer value) field. Specifically, it uses something similar to the following:

    use B qw( svref_2object SVf_IOK );
    
    sub create_data_dumper_literal {
        my ($x) = @_;  # This copying is important as it "resolves" magic.
        return "undef" if !defined($x);
    
        my $sv = svref_2object(\$x);
        my $iok = $sv->FLAGS & SVf_IOK;
        return "$x" if $iok;
    
        $x =~ s/(['\\])/\\$1/g;
        return "'$x'";
    }
    

    You could use similar tricks. But keep in mind,

    • It'll be very hard to stringify floating point numbers without loss. (Floating pointer numbers are identified using $sv->FLAGS & SVf_NOK.)

    • You need to properly escape certain bytes (e.g. NUL) in string literals.

    • A scalar can have more than one value stored in it. For example, !!0 contains a string (the empty string), a floating point number (0) and a signed integer (0). As you can see, the different values aren't even always equivalent. For a more dramatic example, check out the following:

      $ perl -E'open($fh, "non-existent"); say 0+$!; say "".$!;'
      2
      No such file or directory
      

提交回复
热议问题