tags:

views:

143

answers:

3

What's happening behind the scenes when I do a concatenation on a string?

my $short = 'short';
$short .= 'cake';

Is Perl effectively creating a new string, then assigning it the correct variable reference, or are Perl strings always mutable by nature?

The motivation for this question came from a discussion I had with a colleague, who said that scripting languages can utilize immutable strings.

+10  A: 

Perl strings are definitely mutable. Each will store an allocated buffer size in addition to the used length and beginning offset, and the buffer will be expanded as needed. (The beginning offset is useful to allow consumptive operations like s/^abc// to not have to move the actual data.)

ysth
@ysth : Is there a hard reference to this in `perldoc`?
Zaid
@Zaid: not that I know of offhand
ysth
A: 
$short = 'short';
print \$short;

$short .= 'cake';
print \$short;

After executing this code I get "SCALAR(0x955f468)SCALAR(0x955f468)". My answer would be 'mutable'.

hlynur
Perl scalars are actually composed of two separate sections; one of fixed size, and an optional one of variable (depending on type of values stored) size. The address there is of the fixed size component; it's entirely plausible that the variable component be swapped out for a new one. But in fact this is not the case. :)
ysth
+9  A: 

Perl strings are mutable. Perl automatically creates new buffers, if required.

use Devel::Peek;
my $short = 'short';

Dump($short);
Dump($short .= 'cake');
Dump($short = "");

SV = PV(0x28403038) at 0x284766f4
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x28459078 "short"\0
  CUR = 5
  LEN = 8
SV = PV(0x28403038) at 0x284766f4
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x28458120 "shortcake"\0
  CUR = 9
  LEN = 12
SV = PV(0x28403038) at 0x284766f4
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x28458120 ""\0
  CUR = 0
  LEN = 12

Note that no new buffer is allocated in the third case.

eugene y
Perl uses realloc, which may or may not get an entirely new buffer
ysth
Note that perl allocates room for a trailing nul, even though it doesn't use it to determine length. Also note that wherever possible it knows the granularity of the malloc library and rounds allocations up
ysth