in reply to How can I test for the representation of an integer?

Hi sm@sh,

I don't know much about the internals, but from what I do know I'd guess it might be looking at the POK/IOK flags:

$ perl -MDevel::Peek -e 'Dump(1); Dump("1")'; SV = IV(0x21490e8) at 0x21490f8 REFCNT = 1 FLAGS = (IOK,READONLY,PROTECT,pIOK) IV = 1 SV = PV(0x2129fa0) at 0x2149168 REFCNT = 1 FLAGS = (POK,IsCOW,READONLY,PROTECT,pPOK) PV = 0x218fef0 "1"\0 CUR = 1 LEN = 10 COW_REFCNT = 0 $ perl -MDevel::Peek -e '$a=42; $a="Hello"; Dump($a)'; SV = PVIV(0x83d2e0) at 0x8321f0 REFCNT = 1 FLAGS = (POK,IsCOW,pPOK) IV = 42 PV = 0x834920 "Hello"\0 CUR = 5 LEN = 10 COW_REFCNT = 1

However, the much bigger question on my mind is why you need to know this? Perl "casts" between strings and numbers transparently, except for the case where a string can't be converted to a number, which you can determine beforehand with Scalar::Util's looks_like_number. Are you writing code that needs to peek behind the curtains more than that?

Regards,
-- Hauke D

Replies are listed 'Best First'.
Re^2: How can I test for the representation of an integer?
by sm@sh (Acolyte) on Apr 25, 2016 at 10:13 UTC

    Here's why - two regexps which return an array with the same result, but for different reasons

    ~$ perl -MData::Dumper -e 'print Dumper("1" =~ /1/)' $VAR1 = 1; ~$ perl -MData::Dumper -e 'print Dumper("1" =~ /(1)/)' $VAR1 = '1';

      One is a match and the other is a count - you can tell that from the different ways you have constructed the regex. By choosing a confusing value to test against makes this less obvious. Instead try with "2":

      $ perl -MData::Dumper -e 'print Dumper("2" =~ /2/);' $VAR1 = 1; $ perl -MData::Dumper -e 'print Dumper("2" =~ /(2)/);' $VAR1 = '2';

        Hi hippo,

        I think you're thinking of s///g, since m// doesn't return a count (perlop):

        $ perl -MData::Dumper -e 'print Dumper( "abbbbc"=~/b/ )' $VAR1 = 1; $ perl -MData::Dumper -e 'print Dumper( "abbbbc"=~/(b)/ )' $VAR1 = 'b'; $ perl -MData::Dumper -e 'print Dumper(scalar("abbbbc"=~/b/ ))' $VAR1 = 1; $ perl -MData::Dumper -e 'print Dumper(scalar("abbbbc"=~/(b)/ ))' $VAR1 = 1; $ perl -MData::Dumper -e 'print Dumper(scalar("abbbbc"=~/b/g ))' $VAR1 = 1; $ perl -MData::Dumper -e 'print Dumper(scalar("abbbbc"=~/(b)/g))' $VAR1 = 1; $ perl -MData::Dumper -e 'print Dumper( "abbbbc"=~/b/g )' $VAR1 = 'b'; $VAR2 = 'b'; $VAR3 = 'b'; $VAR4 = 'b'; $ perl -MData::Dumper -e 'print Dumper( "abbbbc"=~/(b)/g )' $VAR1 = 'b'; $VAR2 = 'b'; $VAR3 = 'b'; $VAR4 = 'b';

        To get a count you need to use the =()= trick (perlsecret):

        $ perl -MData::Dumper -e 'print Dumper(scalar(()="abbbbc"=~/b/g))' $VAR1 = 4; $ perl -MData::Dumper -e 'print Dumper(scalar(()="abbbbc"=~/(b)/g))' $VAR1 = 4;

        Regards,
        -- Hauke D

        The regexps are user-supplied and arbitrary - they may or may not have captures.
        Matching the number '1' is a real use-case.

      Hi sm@sh,

      I'm not quite sure I understand yet, could you provide some more context? Are you trying to determine whether a regex had capture groups or not? If so, how about this?

      "1" =~ /1/; print @->1?"yes\n":"no\n"; "1" =~ /(1)/; print @->1?"yes\n":"no\n"; __END__ no yes

      This uses the special variable @-, aka @LAST_MATCH_START.

      Update 2018-09-01: Actually, @+ will give you the number of capture groups! See my reply below for the difference.

      Regards,
      -- Hauke D

        Thanks - that's very interesting (@LAST_MATCH_START).
        Sorry I wasn't clear about the use case, but I'm now curious about the representation - I'm aware there are many ways to test the regexp status.
        I had been using $& to test for the general match state, but that can perform badly.