Dr.Ruud wrote: > > Rob Dixon schreef: >> >> Dr.Ruud wrote: >>> >>> Rob Dixon wrote: >>>> >>>> A scalar cannot have multiple 'personalities' - it can have a >>>> maximum of two (its inherent type and a string equivalent) at any >>>> one time, but usually has only one. >>> >>> It can at least have 3: an integer numeric one, a floating numeric >>> one, and a string one. It can have more. >> >> No. It can be just a string; an integer and a string; a double and a >> string; or a reference (pointer) and a string. After that there's >> some weird stuff that goes on with tied scalars and so on. Basically >> every scalar data type keeps space for a pointer to its string >> equivalent as well, presumably because it's a useful thing to >> remember once it has been evaluated once. > > > 1: all three of IOK and NOK and POK are set. > > perl -Mstrict -Mwarnings -MData::Dumper -MDevel::Peek=Dump -wle' > > my $s = "x"; > defined($s) and do { > no warnings "numeric"; > $s eq "" and 1; > $s == $_ and 1 for 0, 0.1; > }; > print "\n", Dumper($s); > Dump $s; > ' > > $VAR1 = 'x'; > > SV = PVNV(0x8a19cb8) at 0x89bad2c > REFCNT = 1 > FLAGS = (PADBUSY,PADMY,IOK,NOK,POK,pIOK,pNOK,pPOK) > IV = 0 > NV = 0 > PV = 0x89b6548 "x"\0 > CUR = 1 > LEN = 2 > > > 2: lossy, so no IOK. > > perl -Mstrict -Mwarnings -MData::Dumper -MDevel::Peek=Dump -wle' > > my $s = "122.99999999999999"; > defined($s) and do { > no warnings "numeric"; > $s eq "" and 1; > $s == $_ and 1 for 0, 0.1; > }; > print "\n", Dumper($s); > Dump $s; > ' > > $VAR1 = '122.99999999999999'; > > SV = PVNV(0x88aba40) at 0x884cc3c > REFCNT = 1 > FLAGS = (PADBUSY,PADMY,NOK,POK,pIOK,pNOK,pPOK) > IV = 122 > NV = 123 > PV = 0x8848700 "122.99999999999999"\0 > CUR = 18 > LEN = 19 > > > 3: a numeric string, touched by numeric comparisons, so returned as a > number by Dumper; again all of IOK, NOK and POK are set. > > perl -Mstrict -Mwarnings -MData::Dumper -MDevel::Peek=Dump -wle' > > my $s = "123"; > $ARGV[0] and defined($s) and do { > no warnings "numeric"; > $s eq "" and 1; > $s == $_ and 1 for 0, 0.1; > }; > print "\n", Dumper($s); > Dump $s; > ' 1 > > $VAR1 = 123; > > SV = PVNV(0x8160dd0) at 0x8101be8 > REFCNT = 1 > FLAGS = (PADBUSY,PADMY,IOK,NOK,POK,pIOK,pNOK,pPOK) > IV = 123 > NV = 123 > PV = 0x80fd450 "123"\0 > CUR = 3 > LEN = 4 > > > I would say that 1 and 3 have three personalities. > And 2 has nearly three. :)
First of all I would say that all of these are NV values (double floats), and as I have said scalar values always allow for PV (string) equivalents. What I was unaware of was that the NV structure also includes space for an IV (integer) equivalent. Other than that your results are as I described, and what you are really defending is your comment here > Dr.Ruud wrote: > > There is no real way to test if a value inside a variable has a numeric > "personality". Variables can have multiple "personalities", each with there > own binary value. > Rob Dixon wrote: > > A scalar cannot have multiple 'personalities' - it can have a maximum of two > (its inherent type and a string equivalent) at any one time, but usually has > only one. It will be given an additional string value only if it needs one for > some reason. This is one reason why quoting variables - "$val" - is a bad idea > in general, because it both forces conversion and occupies memory > unnecessarily. > > There is indeed a simple way to test in Perl whether a scalar value is being > treated as a string (I'm sure this is one or Randal's, but I can't find the > reference) > > print "Non-string" if ($val & ~$val) eq '0'; > > And also, since Data::Dumper does it there clearly is a way for a module to do > it in general. And to be honest I think that if you're allowing 'multiple' to include 'three' it may as well include 'two' as well :) > 4: make $s blessed too. > > perl -Mstrict -Mwarnings -MData::Dumper -MDevel::Peek=Dump -wle' > > my $s = "123"; > bless \$s, "test"; > defined($s) and do { > no warnings "numeric"; > $s eq "" and 1; > $s == $_ and 1 for 0.1, 0; > }; > print "\n", Dumper($s); > Dump $s; > ' > > $VAR1 = 123; > > SV = PVMG(0x90f5618) at 0x9068c44 > REFCNT = 1 > FLAGS = (PADBUSY,PADMY,OBJECT,IOK,NOK,POK,pIOK,pNOK,pPOK) > IV = 123 > NV = 123 > PV = 0x9064460 "123"\0 > CUR = 3 > LEN = 4 > STASH = 0x9063cf4 "test" > > That last one is an example of what I named "more". A PVMG is a 'magical', and that is a whole separate consideration that I don't think belongs here. I hope it summarises this thread to your satisfaction if I make these points - A simple scalar variable may have up to three valid values simultaneously: a string value, and integer value, and a double float value - It is straightforward for a Perl module with a C component to examine which values are valid, and behave accordingly - Forcing a conversion to a string or a numeric is easy in Perl, using $val.'' or $val+0 respectively. Just to make things worse, I see that Perl 5.10 has moved the pointer to the string value from the body of the structure up to the header, so that it is now svu_pv instead of xp_pv. Also, string and integer structures (xpv and xpviv) now have space for a double value as well. Oddly though, there is no allowance in xpv for an integer value. This stuff has stayed pretty much constant since Perl 5.4 and it seems I have a lot of reading to do! Rob -- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] http://learn.perl.org/