${ X() } . ${ X() } concat( deref( X() ), deref( X() ), ) #### ${ X() } . ' ' . ${ X() } concat( concat( deref( X() ), ' ', ), deref( X() ), ) #### ${ X() } . ${ X() } concat( new( deref( X() ) ), deref( X() ), ) #### ${ X() } . ' ' . ${ X() } concat( concat( new( deref( X() ) ), ' ', ), deref( X() ), ) #### use strict; use warnings; use feature qw( say ); package ike; { sub concat { $_[0] . $_[1] } sub deref :lvalue { ${ $_[0] } } my $a = \ '1'; my $b = \ '2'; say concat( deref( $a ), deref( $b ), ); say $$a; say <<'EOS'; Note: $$a has not changed, So, $$a was copied to produce the concatenation 1 + 1 = 2 bytes copied. EOS say concat( concat( deref( $a ), ' ', ), deref( $b ), ); say <<'EOS'; Note: $$a has not changed, So, $$a was copied to produce the concatenation Therefore, the whole of that result was copied (again) to produce the result of the second concatenation. ( 1 + 1 ) * 2 + 1 = 5 bytes copied. EOS } package buk; { sub concat { $_[0] .= $_[1] } sub deref { ${ $_[0] } } sub new{ "$_[0]" } my $a = \ '1'; my $b = \ '2'; say concat( concat( new( deref( $a ) ), ' ', ), deref( $b ), ); say <<'EOS'; New copies 1 byte its arg into a new string The first concat() copes the space and apend it to the new string. The second concat() copies 1 byte from $b and apend it to that. 1 + 1 + 1 = 3 bytes copied. EOS } __END__ C:\test>junk999 12 1 Note: $$a has not changed, So, $$a was copied to produce the concatenation 1 + 1 = 2 bytes copied. 1 2 Note: $$a has not changed, So, $$a was copied to produce the concatenation Therefore, the whole of that result was copied (again) to produce the result of the second concatenation. ( 1 + 1 ) * 2 + 1 = 5 bytes copied. 1 2 New copies 1 byte its arg into a new string The first concat() copes the space and apend it to the new string. The second concat() copies 1 byte from $b and apend it to that. 1 + 1 + 1 = 3 bytes copied.