Text or Number
Sisyphus
kalinabears at iinet.net.au
Sat Mar 27 22:08:49 CST 2004
Andrew Savige wrote:
> Joshua Goodall <joshua at roughtrade.net> wrote:
>
>>#!/usr/bin/perl
>>use B qw(svref_2object);
>>sub cmpflags($$) { $_[1] & svref_2object($_[0])->FLAGS ? 1 : undef }
>>sub isinteger($) { cmpflags \$_[0], B::SVf_IOK | B::SVp_IOK }
>>sub isstring ($) { cmpflags \$_[0], B::SVf_POK | B::SVp_POK }
>>
>>$a=42; $b=$a; $c=$a; $d="$c";
>>for $i ($a, $b, $c, $d) {
>> printf "%2s: int=%1s str=%1s\n", $i, isinteger($i), isstring($i);
>>}
>
>
> for $i ($a, $b, $c, $d) {
> my $is_string = (~$i & $i) ne '0';
> printf "%2s: int=%1s str=%1s\n", $i, !$is_string, $is_string;
> }
>
> This old merlyn trick exploits that bitwise operators ~ and & operate
> differently on numbers and strings. Notice that Joshua's prints:
>
> 42: int=1 str=
> 42: int=1 str=
> 42: int=1 str=1
> 42: int= str=1
>
> while merlyn's trick prints:
>
> 42: int=1 str=
> 42: int=1 str=
> 42: int=1 str=
> 42: int= str=1
>
> Why the difference?
The assignment $d = "$c" is altering the flags associated with $c -
which produces that strange result in running Joshua's code.
If you take a Devel::Peek::Dump($c) immediately after the assignment
$c=$a, you'll see FLAGS = (IOK,pIOK). If you take another
Devel::Peek::Dump($c) after the assignment $d="$c", you'll see FLAGS =
(IOK,POK,pIOK,pPOK).
Mind you, I don't know why that should be so :-)
> Also, I'm curious to know which type of applications
> care about this (in the original question, I didn't understand exactly
> how this was causing trouble).
>
Yes I'm not sure I understand, either - though my guess is that the OP
would want *all* of the above to be reported as a number - which is what
the perl API function 'looks_like_number()' would do, if I'm not mistaken.
Cheers,
Rob
--
Any emails containing attachments will be deleted from my ISP's mail
server before I even get to see them. If you wish to email me an
attachment, please provide advance warning so that I can make the
necessary arrangements.
More information about the Melbourne-pm
mailing list