27

In Perl, what is the difference between

$status = 500;

and

$status = '500';
Ry-
  • 218,210
  • 55
  • 464
  • 476
ado
  • 1,451
  • 3
  • 17
  • 27
  • 4
    possible duplicate of [When does the difference between a string and a number matter in Perl 5?](http://stackoverflow.com/questions/2980550/when-does-the-difference-between-a-string-and-a-number-matter-in-perl-5) – Ilmari Karonen Jun 27 '13 at 08:25
  • If the status is numeric, assign a number. If it's a string, assign a string. Note that a string that consists of digits only is not necessarily a numeric quantity (as in "social security number"). – Ingo Jun 27 '13 at 16:05

9 Answers9

38

Not much. They both assign five hundred to $status. The internal format used will be different initially (IV vs PV,UTF8=0), but that's of no importance to Perl.

However, there are things that behave different based on the choice of storage format even though they shouldn't. Based on the choice of storage format,

  • JSON decides whether to use quotes or not.
  • DBI guesses the SQL type it should use for a parameter.
  • The bitwise operators (&, | and ^) guess whether their operands are strings or not.
  • open and other file-related builtins encode the file name using UTF-8 or not. (Bug!)
  • Some mathematical operations return negative zero or not.
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • 2
    If you pass that number through a JSON constructor, one will output "500", the other will output 500 – alexk Jun 30 '13 at 19:43
21

As already @ikegami told not much. But remember than here is MUCH difference between

$ perl -E '$v=0500; say $v'

prints 320 (decimal value of 0500 octal number), and

$ perl -E '$v="0500"; say $v'

what prints

0500

and

$ perl -E '$v=0900; say $v'

what dies with error:

Illegal octal digit '9' at -e line 1, at end of line
Execution of -e aborted due to compilation errors.

And

perl -E '$v="0300";say $v+1'

prints

301

but

perl -E '$v="0300";say ++$v'

prints

0301

similar with 0x\d+, e.g:

$v = 0x900;
$v = "0x900";
clt60
  • 62,119
  • 17
  • 107
  • 194
  • awesome reply i shall save in my perl details&thingies folder – ado Jun 27 '13 at 02:06
  • 3
    This seems a bit irrelevant to the question to be the selected answer IMO – plusplus Jun 27 '13 at 11:57
  • Please, don't start any flamewar. ;( My perl knowledge is only a fraction of Ikegami's (and others) knowledge - only tried help from my "level". As pulsplus told - it is probably offtopic. Sorry for this. – clt60 Jun 27 '13 at 16:08
  • 1
    @jm666, Also, `4+4` is different than `'4+4'`. This comes up a lot in questions concerning interpolation. – ikegami Jun 30 '13 at 20:00
  • 1
    @cajwine, You say you don't want to know the internal details. I fully agree with that, which is why I didn't go into them. But then you complain that I didn't go into details about the internals? I mentioned exactly what you needed to look into if you wanted to dive into the guts. Did you look up IV and PV? [illguts](http://search.cpan.org/dist/illguts/) is a good read. – ikegami Jun 30 '13 at 23:02
  • @cajwine, No, my answer is not that X and Y are both carbon (when it would be more useful to say they're diamond and graphite); my answer is that X and Y are both diamonds (five hundred). One's from the south side of the mine; the other the north, but noone cares. You seem to have misunderstood my answer. – ikegami Jul 02 '13 at 00:47
  • @cajwine - my point was nothing to do with levels of answers, just that starting to talk about octal numbers was not the most helpful to the question, which quite clearly asks about the difference between `500` and `"500"`. The answer is still interesting and useful, and a welcome addition to the discussion, but just shouldn't be the selected answer because it's not really answering the OP's question – plusplus Jul 11 '13 at 12:49
19

There is only a difference if you then use $var with one of the few operators that has different flavors when operating on a string or a number:

$string = '500';
$number = 500;
print $string & '000', "\n";
print $number & '000', "\n";

output:

000
0
ysth
  • 96,171
  • 6
  • 121
  • 214
8

To provide a bit more context on the "not much" responses, here is a representation of the internal data structures of the two values via the Devel::Peek module:

user@foo ~ $ perl -MDevel::Peek -e 'print Dump 500; print Dump "500"'
SV = IV(0x7f8e8302c280) at 0x7f8e8302c288
  REFCNT = 1
  FLAGS = (PADTMP,IOK,READONLY,pIOK)
  IV = 500
SV = PV(0x7f8e83004e98) at 0x7f8e8302c2d0
  REFCNT = 1
  FLAGS = (PADTMP,POK,READONLY,pPOK)
  PV = 0x7f8e82c1b4e0 "500"\0
  CUR = 3
  LEN = 16

Here is a dump of Perl doing what you mean:

user@foo ~ $ perl -MDevel::Peek -e 'print Dump ("500" + 1)'
SV = IV(0x7f88b202c268) at 0x7f88b202c270
  REFCNT = 1
  FLAGS = (PADTMP,IOK,READONLY,pIOK)
  IV = 501
6

The first is a number (the integer between 499 and 501). The second is a string (the characters '5', '0', and '0'). It's not true that there's no difference between them. It's not true that one will be converted immediately to the other. It is true that strings are converted to numbers when necessary, and vice-versa, and the conversion is mostly transparent, but not completely.

The answer When does the difference between a string and a number matter in Perl 5 covers some of the cases where they're not equivalent:

  • Bitwise operators treat numbers numerically (operating on the bits of the binary representation of each number), but they treat strings character-wise (operating on the bits of each character of each string).
  • The JSON module will output a string as a string (with quotes) even if it's numeric, but it will output a number as a number.
  • A very small or very large number might stringify differently than you expect, whereas a string is already a string and doesn't need to be stringified. That is, if $x = 1000000000000000 and $y = "1000000000000000" then $x might stringify to 1e+15. Since using a variable as a hash key is stringifying, that means that $hash{$x} and $hash{$y} may be different hash slots.
  • The smart-match (~~) and given/when operators treat number arguments differently from numeric strings. Best to avoid those operators anyway.
Community
  • 1
  • 1
hobbs
  • 223,387
  • 19
  • 210
  • 288
3

There are different internally:)

($_ ^ $_) ne '0' ? print "$_ is string\n" : print "$_ is numeric\n" for (500, '500');

output:

500 is numeric
500 is string
ernix
  • 3,442
  • 1
  • 17
  • 23
3

I think this perfectly demonstrates what is going on.

$ perl -MDevel::Peek -e 'my ($a, $b) = (500, "500");print Dump $a; print Dump $b; $a.""; $b+0; print Dump $a; print Dump $b'
SV = IV(0x8cca90) at 0x8ccaa0
  REFCNT = 1
  FLAGS = (PADMY,IOK,pIOK)
  IV = 500
SV = PV(0x8acc20) at 0x8ccad0
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x8c5da0 "500"\0
  CUR = 3
  LEN = 16
SV = PVIV(0x8c0f88) at 0x8ccaa0
  REFCNT = 1
  FLAGS = (PADMY,IOK,POK,pIOK,pPOK)
  IV = 500
  PV = 0x8d3660 "500"\0
  CUR = 3
  LEN = 16
SV = PVIV(0x8c0fa0) at 0x8ccad0
  REFCNT = 1
  FLAGS = (PADMY,IOK,POK,pIOK,pPOK)
  IV = 500
  PV = 0x8c5da0 "500"\0
  CUR = 3
  LEN = 16

Each scalar (SV) can have string (PV) and or numeric (IV) representation. Once you use variable with only string representation in any numeric operation and one with only numeric representation in any string operation they have both representations. To be correct, there can be also another number representation, the floating point representation (NV) so there are three possible representation of scalar value.

Hynek -Pichi- Vychodil
  • 26,174
  • 5
  • 52
  • 73
2

Many answers already to this question but i'll give it a shot for the confused newbie:

my $foo = 500;
my $bar = '500';

As they are, for practical pourposes they are the "same". The interesting part is when you use operators. For example:

print $foo + 0;

output: 500

The '+' operator sees a number at its left and a number at its right, both decimals, hence the answer is 500 + 0 => 500

print $bar + 0;

output: 500

Same output, the operator sees a string that looks like a decimal integer at its left, and a zero at its right, hence 500 + 0 => 500

But where are the differences? It depends on the operator used. Operators decide what's going to happen. For example:

my $foo = '128hello';
print $foo + 0;
output: 128

In this case it behaves like atoi() in C. It takes biggest numeric part starting from the left and uses it as a number. If there are no numbers it uses it as a 0.

How to deal with this in conditionals?

my $foo = '0900';
my $bar = 900;
if( $foo == $bar)
{print "ok!"}
else
{print "not ok!"}

output: ok!

== compares the numerical value in both variables. if you use warnings it will complain about using == with strings but it will still try to coerce.

my $foo = '0900';
my $bar = 900;
if( $foo eq $bar)
{print "ok!"}
else
{print "not ok!"}

output: not ok!

eq compares strings for equality.

AlfredoVR
  • 4,069
  • 3
  • 25
  • 33
0

You can try "^" operator.

my $str  = '500';
my $num  = 500;

if ($num ^ $num)
{
    print 'haha\n';
}

if ($str ^ $str)
{
    print 'hehe\n';
}

$str ^ $str is different from $num ^ $num so you will get "hehe". ps, "^" will change the arguments, so you should do

my $temp = $str;
if ($temp ^ $temp )
{
    print 'hehe\n';
}

. I usually use this operator to tell the difference between num and str in perl.

Rikku121
  • 2,536
  • 2
  • 23
  • 38
asenxu08
  • 5
  • 1