in reply to Need some wisdom on strings to numbers

Edit: almut beat me to it. Thats what I get for walking the dogs mid-post.

A couple of things...

First, it probably should not matter to you whether something is a 'string' or a 'number', as internally perl will convert it between strings and numbers as needed. The only use case I can think of for needing to care is if you are passing things to a serialization routine, where the output is destined for another programming language where it matters.

Second, I'm not sure I'd take the output of Data::Dumper at face value. Since from perl's perspective 123.1 is more or less the same as '123.1', it may just display the string.

If you really care to see the internal representation of a perl variable, you can use Devel::Peek.

use Devel::Peek qw| Dump |; my $x = 123.1; my $y = '123.10'; my $z = $y + 0; Dump $x; Dump $y; Dump $z;

Outputs

SV = NV(0x81ac10) at 0x801794 REFCNT = 1 FLAGS = (PADBUSY,PADMY,NOK,pNOK) NV = 123.1 SV = PVNV(0x8044d0) at 0x801770 REFCNT = 1 FLAGS = (PADBUSY,PADMY,NOK,POK,pIOK,pNOK,pPOK) IV = 123 NV = 123.1 PV = 0x301200 "123.10"\0 CUR = 6 LEN = 8 SV = NV(0x81ac20) at 0x801788 REFCNT = 1 FLAGS = (PADBUSY,PADMY,NOK,pNOK) NV = 123.1

So, as you can see, $x and $z are strictly NVs ( numeric values ) while $y is a PVNV, which has both numeric and string values contained. More information on the 'c' types for perl variables can be found in perlguts.

-- AlexLC

Replies are listed 'Best First'.
Re^2: Need some wisdom on strings to numbers
by decebel (Acolyte) on Oct 07, 2009 at 03:53 UTC
    Hi there,

    Thanks all for the prompt reply. I am passing the hash to an in-memory database (MongoDB) which serializes the hash into a json style structure. This causes the first variable (123) to remain as an int but the second one 123.1 gets in as a string and I think this is because the hash stores this value as a string. Any suggestions?

      As an afterthought to Alex's reply, is there a work around when we are serializing the data structure?

        Is it actually a problem that JSON is making 123.1 into a '123.1' as it goes into mongodb? If you are pulling it back out again in perl, then it shouldn't matter.

        If it does matter, then the workaround is going to be dependant on what library does the serialization. If it is JSON.pm, then what you are doing ( add zero, or multiply by 1 ) should make sure that things are encoded as numbers.

        It appears that JSON.pm is doing things correctly.

        use JSON::PP; use JSON::XS; use JSON::Syck; my $x = 123.1; my $y = '123.10'; my $z = $y + 0; my $h = { x => $x, y => $y, z => $z }; print JSON::PP::encode_json($h) . "\n"; print JSON::XS::encode_json($h) . "\n"; print JSON::Syck::Dump($h) . "\n"; __END__ {"y":"123.10","x":123.1,"z":123.1} #JSON::PP {"y":"123.10","x":123.1,"z":123.1} #JSON::XS {"y":123.10,"x":123.1,"z":123.1} #JSON::Syck ( seems to do $y wrong/ +differently )
        -- AlexLC