Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl variable assignment side effects

Tags:

perl

I'll be the first to admit that Perl is not my strong suit. But today I ran across this bit of code:

my $scaledWidth = int($width1x * $scalingFactor);
my $scaledHeight = int($height1x * $scalingFactor);
my $scaledSrc = $Media->prependStyleCodes($src, 'SX' . $scaledWidth);

# String concatenation makes this variable into a
# string, so we need to make it an integer again.
$scaledWidth = 0 + $scaledWidth;

I could be missing something obvious here, but I don't see anything in that code that could make $scaledWidth turn into a string. Unless somehow the concatenation in the third line causes Perl to permanently change the type of $scaledWidth. That seems ... wonky.

I searched a bit for "perl assignment side effects" and similar terms, and didn't come up with anything.

Can any of you Perl gurus tell me if that commented line of code actually does anything useful? Does using an integer variable in a concatenation expression really change the type of that variable?

like image 521
Jim Mischel Avatar asked Nov 16 '25 23:11

Jim Mischel


1 Answers

It is only a little bit useful.

Perl can store a scalar value as a number or a string or both, depending on what it needs.

use Devel::Peek;
Dump($x = 42);
Dump($x = "42");

Outputs:

SV = PVIV(0x139a808) at 0x178a0b8
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 42
  PV = 0x178d9e0 "0"\0
  CUR = 1
  LEN = 16

SV = PVIV(0x139a808) at 0x178a0b8
  REFCNT = 1
  FLAGS = (POK,pPOK)
  IV = 42
  PV = 0x178d9e0 "42"\0
  CUR = 2
  LEN = 16

The IV and IOK tokens refer to how the value is stored as a number and whether the current integer representation is valid, while PV and POK indicate the string representation and whether it is valid. Using a numeric scalar in a string context can change the internal representation.

use Devel::Peek;
$x = 42;
Dump($x);
$y = "X" . $x;
Dump($x);

SV = IV(0x17969d0) at 0x17969e0
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 42

SV = PVIV(0x139aaa8) at 0x17969e0
  REFCNT = 1
  FLAGS = (IOK,POK,pIOK,pPOK)
  IV = 42
  PV = 0x162fc00 "42"\0
  CUR = 2
  LEN = 16

Perl will seamlessly convert one to the other as needed, and there is rarely a need for the Perl programmer to worry about the internal representation.

I say rarely because there are some known situations where the internal representation matters.

like image 162
mob Avatar answered Nov 18 '25 20:11

mob