Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re^3: Converting to number doesn't always work...

by AnomalousMonk (Archbishop)
on Nov 23, 2019 at 09:24 UTC ( [id://11109101]=note: print w/replies, xml ) Need Help??


in reply to Re^2: Converting to number doesn't always work...
in thread Converting to number doesn't always work...

Here's something to ponder:

c:\@Work\Perl\monks>perl -wMstrict -e "my @TEST_VALUES = ('55a', 'a55'); foreach my $i (@TEST_VALUES) { print qq{Calling TEST('$i') / }; print qq{TEST return values = @{[ TEST($i) ]} \n\n}; } ;; sub TEST { my $N = shift; local $SIG{__WARN__} = sub { print qq{(warn: N=$N -> }; $N = 77; print qq{N=$N) / }; }; print qq{N=$N / N+0=}, $N + 0; print qq{ / N.''=}, $N.'', qq{\n}; return $N, $N+0, $N.''; } " Calling TEST('55a') / (warn: N=55a -> N=77) / N=55a / N+0=55 / N.''=77 TEST return values = 77 55 77 Calling TEST('a55') / (warn: N=a55 -> N=77) / N=a55 / N+0=0 / N.''=77 TEST return values = 77 0 77
Don't ask me what this means or if it's a bug (it's late and I need to think about this with a clear head), but I suspect it has something to do with the inherent dualvar nature of scalars (see Scalar::Util::dualvar): a scalar caches a string or numeric representation of its value if it was ever used as a string or number, and both representations may be present in the scalar at the same time and may represent entirely unrelated values! Runs the same under ActiveState 5.8.9 and Strawberry 5.14.4.1.


Give a man a fish:  <%-{-{-{-<

Replies are listed 'Best First'.
Re^4: Converting to number doesn't always work...
by haukex (Archbishop) on Nov 23, 2019 at 16:42 UTC

    That's definitely a strange behavior, here's a fairly short way to reproduce it:

    $ perl -wMstrict -MDevel::Peek -le 'my $x="11a"; $SIG{__WARN__} = sub{$x="99"}; print "num: ",$x+0,", str: $x"; Dump($x)' num: 11, str: 99 SV = PVNV(0x59efe266a440) at 0x59efe2692648 REFCNT = 2 FLAGS = (POK,IsCOW,pIOK,pNOK,pPOK) IV = 11 NV = 11 PV = 0x59efe26d3ae0 "99"\0 CUR = 2 LEN = 10 COW_REFCNT = 1

    My guess is it's the signal handler: I am guessing it gets called during the $n+0 operation which produces the warning, and so an assignment to the string component of the variable during that operation leaves it in a state where the string and numeric components differ. So it's very similar to:

    $ perl -wMstrict -MDevel::Peek -MScalar::Util=dualvar -e 'my $x=dualvar(11,"99"); Dump($x)'

    I'm not sure if this is worth a bug report or not.

      expanding on AnomalousMonk's code and haukex's, it does seem like the sig handler has something to do with this. It appears to be activating the NV slot of the scalar.

      When perl then does its DWIM conversions, it is preferring the double over the int, so I would percieve that the scalar is something a little more complex than just a dualvar.

      Also worth noting sig handling on some operating systems are implemented differently. how much impact this is having I am unsure of

      use strict; use warnings; use Devel::Peek; $|++; my @TEST_VALUES = ('a55','55a'); foreach my $i (@TEST_VALUES) { print qq{\nCalling TEST('$i') / \n}; print qq{\nTEST return values = @{[ TEST($i) ]} \n\n}; } sub TEST { my $N = shift; local $SIG{__WARN__} = sub { $|++; print "in_warn\n"; # my $subref = sub { $|++; print "in_subref\n"; Dump $N; print qq{(warn: N=$N -> }; $N = 77; print qq{N=$N) / \n}; Dump $N; print "outta_subref\n"; }; print "in_test\n"; Dump $N; # my $tmp_value = $subref->(); print qq{N=$N / N+0=}, $N + 0; print qq{ / N.''=}, $N.'', qq{\n}; print "outta_test returning $N, $N+0, $N.''\n"; return $N, $N+0, $N.''; } =head1 output Calling TEST('a55') / in_test SV = PV(0x10a847c) at 0xf9d3dc REFCNT = 2 FLAGS = (PADMY,POK,pPOK) PV = 0xf9055c "a55"\0 CUR = 3 LEN = 12 in_warn SV = PVNV(0x10a9bcc) at 0xf9d3dc REFCNT = 2 FLAGS = (PADMY,POK,pPOK) IV = 0 NV = 0 PV = 0xf9055c "a55"\0 CUR = 3 LEN = 12 (warn: N=a55 -> N=77) / SV = PVNV(0x10a9bcc) at 0xf9d3dc REFCNT = 2 FLAGS = (PADMY,IOK,POK,pIOK,pPOK) IV = 77 NV = 0 PV = 0xf9055c "77"\0 CUR = 2 LEN = 12 outta_subref N=a55 / N+0=0 / N.''=77 outta_test returning 77, 77+0, 77.'' TEST return values = 77 0 77 Calling TEST('55a') / in_test SV = PVNV(0x10a9bcc) at 0xf9d3dc REFCNT = 2 FLAGS = (PADMY,POK,pPOK) IV = 0 NV = 0 PV = 0xf9055c "55a"\0 CUR = 3 LEN = 12 in_warn SV = PVNV(0x10a9bcc) at 0xf9d3dc REFCNT = 2 FLAGS = (PADMY,POK,pPOK) IV = 0 NV = 55 PV = 0xf9055c "55a"\0 CUR = 3 LEN = 12 (warn: N=55a -> N=77) / SV = PVNV(0x10a9bcc) at 0xf9d3dc REFCNT = 2 FLAGS = (PADMY,IOK,POK,pIOK,pPOK) IV = 77 NV = 55 PV = 0xf9055c "77"\0 CUR = 2 LEN = 12 outta_subref N=55a / N+0=55 / N.''=77 outta_test returning 77, 77+0, 77.'' TEST return values = 77 55 77 =cut
Re^4: Converting to number doesn't always work...
by harangzsolt33 (Chaplain) on Nov 23, 2019 at 14:18 UTC
    but I suspect it has something to do with the inherent dualvar nature of scalars (see Scalar::Util::dualvar): a scalar caches a string or numeric representation of its value if it was ever used as a string or number, and both representations may be present in the scalar at the same time and may represent entirely unrelated values!

    Wow, that is clever! So, it's not really a bug...!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11109101]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (5)
As of 2024-03-28 20:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found