<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Effective Perler &#187; references</title>
	<atom:link href="http://www.effectiveperlprogramming.com/blog/category/book/chapters/references/feed" rel="self" type="application/rss+xml" />
	<link>http://www.effectiveperlprogramming.com</link>
	<description>Effective Perl Programming - write better, more idiomatic Perl</description>
	<lastBuildDate>Sat, 28 Jan 2012 02:19:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Enchant closures for better debugging output</title>
		<link>http://www.effectiveperlprogramming.com/blog/1345</link>
		<comments>http://www.effectiveperlprogramming.com/blog/1345#comments</comments>
		<pubDate>Sun, 18 Sep 2011 18:06:55 +0000</pubDate>
		<dc:creator>brian d foy</dc:creator>
				<category><![CDATA[item]]></category>
		<category><![CDATA[object-oriented programming]]></category>
		<category><![CDATA[references]]></category>
		<category><![CDATA[subroutines]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=1345</guid>
		<description><![CDATA[When you&#8217;re using code references heavily, you&#8217;re going to have a problem figuring out which one of them is having a problem. You define them in possibly several and far-flung parts of your program, but when it comes to using them, you don&#8217;t know which one you are using. You can&#8217;t really print its value [...]]]></description>
			<content:encoded><![CDATA[<p>When you&#8217;re using code references heavily, you&#8217;re going to have a problem figuring out which one of them is having a problem. You define them in possibly several and far-flung parts of your program, but when it comes to using them, you don&#8217;t know which one you are using. You can&#8217;t really print its value like you would for a scalar, making it more difficult for you to debug things. You can dereference a scalar or an array to see what it is, but you can&#8217;t dereference a code reference without making it do something.</p>
<p>Consider this code, which defines a code reference along with other<br />
references (also see <span class="item">Item 59. Compare reference types to prototypes</span>). You can print the values in most reference types to see what they are, but you can&#8217;t do that directly with the code reference:</p>
<pre class="brush:perl">
use v5.10;

my @array = ( \'xyz', [qw(a b c)], sub { say 'Buster' } );

foreach ( @array ) {
	say "$_";
	when( ref eq ref \ ''   ) { say "Scalar $$_" }
	when( ref eq ref []     ) { say "Array @$_" }
	when( ref eq ref sub {} ) { say "Sub ???" }
	}
</pre>
<p>When you dereference a value, nothing happens (aside from any <code>tie</code> magic). When you dereference a subroutine, you run its code with whatever arguments you give to it. If the subroutine needs arguments, which arguments would you use if you wanted to see what the subroutine would do?</p>
<p>There&#8217;s a clever way around this, first noted by Randal Schwartz in his Perlmonks post <a href="http://www.perlmonks.org/?node_id=413725">Track the filename/line number of an anonymous coderef</a>. He proposed a new subroutine, <code>main::Sub</code> to use in place of the <code>sub</code> keyword.</p>
<pre class="brush:perl">
BEGIN {
  package MagicalCoderef;

  use overload '""' => sub {
    require B;

    my $ref = shift;
    my $gv = B::svref_2object($ref)->GV;
    sprintf "%s:%d", $gv->FILE, $gv->LINE;
  };

  sub main::Sub (&#038;) {
    return bless shift, __PACKAGE__;
  }
}
</pre>
<p>This technique actually made the code reference an object so he could overload stringification. </p>
<pre class="brush:perl">
my $s = Sub { say +shift };
print "$s\n";
</pre>
<p>This stringified the code reference as the filename and line number where you created it:</p>
<pre class="brush:plain">
/Users/Buster/Desktop/magic_coderef.pl:19
</pre>
<p>You can go farther than this, though, and make this a bit more useful. In response to Randal&#8217;s post, I suggested turning the idea inside-out. Instead of using <code>Sub</code>, I exposed the object creation. That way, you don&#8217;t have to worry about which package <code>Sub</code> might be in:</p>
<pre class="brush:perl">
use v5.14;

package MagicalCodeRef 0.90 {
    use overload '""' => sub
        {
        require B;

        my $ref = shift;
        my $gv = B::svref_2object($ref)->GV;
        sprintf "%s:%d", $gv->FILE, $gv->LINE;
        };

    sub enchant { bless $_[1], $_[0] }
    }
</pre>
<p>You can apply this magic to code references that you already have to get the same result (you could also do this with <code>Sub</code>, but it looks odd):</p>
<pre class="brush:perl">
my $s = MagicalCodeRef->enchant( sub { say +shift } );
print "$s\n";
</pre>
<p>Still, that&#8217;s not good enough. You where where you created the subroutine, but that might not be enough information for you. You can use even more <code>B</code> magic. The <a href="https://www.metacpan.org/module/B::Deparse">B::Deparse</a> module can decompile code to show you what <code>perl</code> thinks it is (we used this briefly in <span class="item">Item 7. Know which values are false and test them accordingly</span>).</p>
<pre class="brush:perl">
use v5.14;

package MagicalCodeRef 1.00 {
    use overload '""' => sub
        {
        require B;

        my $ref = shift;
        my $gv = B::svref_2object($ref)->GV;

		require B::Deparse;
		my $deparse = B::Deparse->new;
		my $code = $deparse->coderef2text($ref);

        my $string = sprintf "---code ref---\n%s:%d\n%s\n---",
        $gv->FILE, $gv->LINE, $code;

        };

    sub enchant { bless $_[1], $_[0] }
    }
</pre>
<p>With the same bit of code, you get additional output:</p>
<pre class="brush:perl">
my $s = MagicalCodeRef->enchant( sub { say +shift } );
print "$s\n";
</pre>
<p>The output shows everything that <code>perl</code> thinks it needs to reproduce that behavior, including some pragma settings and compiler hints:</p>
<pre class="brush:plain">
---code ref---
/Users/brian/Desktop/magic:25
{
    use strict 'refs';
    BEGIN {
        $^H{'feature_unicode'} = q(1);
        $^H{'feature_say'} = q(1);
        $^H{'feature_state'} = q(1);
        $^H{'feature_switch'} = q(1);
    }
    print shift();
}
---
</pre>
<p>The code doesn&#8217;t look the same as the code reference you initially created, but at least you have an idea what the code reference does.</p>
<p>If the code reference is a closure, you might also need to know which variables it closed over and what their values are. You can get these from the <a href="https://www.metacpan.org/module/PadWalker">PadWalker</a> module (which doesn&#8217;t come with Perl so you&#8217;ll need to get it from CPAN):</p>
<pre class="brush:perl">
use v5.14;

package MagicalCodeRef 1.01 {
    use overload '""' => sub
        {
        require B;

        my $ref = shift;
        my $gv = B::svref_2object($ref)->GV;

		require B::Deparse;
		my $deparse = B::Deparse->new;
		my $code = $deparse->coderef2text($ref);

        require PadWalker;
        my $hash = PadWalker::closed_over( $ref );

		require Data::Dumper;
		local $Data::Dumper::Terse = 1;
        my $string = sprintf "---code ref---\n%s:%d\n%s\n---\n%s---",
        $gv->FILE, $gv->LINE,
        $code,
        Data::Dumper::Dumper( $hash );

        };

    sub enchant { bless $_[1], $_[0] }
    }
</pre>
<p>Give this new version of <code>MagicalCodeRef</code> a closure:</p>
<pre class="brush:perl">
my $sub = do {
	my( $x, $y ) = qw( Buster Mimi );

	sub { print "$x $y @_" }
	};

my $s = MagicalCodeRef->enchant( $sub );
say $s;
</pre>
<p>Now you see that which variables in the code reference refer to lexical variables that are out of scope instead of package or special variables. Only the lexical variables show up in the <code>Dumper</code> output:</p>
<pre class="brush:plain">
---code ref---
/Users/brian/Desktop/magic:35
{
    use strict 'refs';
    BEGIN {
        $^H{'feature_unicode'} = q(1);
        $^H{'feature_say'} = q(1);
        $^H{'feature_state'} = q(1);
        $^H{'feature_switch'} = q(1);
    }
    print "$x $y @_";
}
---
{
  '$y' => \'Mimi',
  '$x' => \'Buster'
}
---
</pre>
<h2>Things to remember</h2>
<ul>
<li>You can bless code references and overload their stringification to output what you like
<li>The <code>B</code> module can tell you the filename and line number where you created the closure
<li>The <code>B::Deparse</code> module can decompile a code reference
<li>The <code>PadWalker</code> module can give you the closed-over<br />
lexical variables and their values.
</ul>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Enchant+closures+for+better+debugging+output+http://tinyurl.com/3lq92dh" title="Post to Twitter"><img class="nothumb" src="http://www.effectiveperlprogramming.com/wp-content/plugins/tweet-this/icons/tt-twitter2.png" alt="Post to Twitter" /></a> <a class="tt" href="http://twitter.com/home/?status=Enchant+closures+for+better+debugging+output+http://tinyurl.com/3lq92dh" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/1345&amp;title=Enchant+closures+for+better+debugging+output" title="Post to Delicious"><img class="nothumb" src="http://www.effectiveperlprogramming.com/wp-content/plugins/tweet-this/icons/tt-delicious.png" alt="Post to Delicious" /></a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/1345&amp;title=Enchant+closures+for+better+debugging+output" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/1345&amp;title=Enchant+closures+for+better+debugging+output" title="Post to Digg"><img class="nothumb" src="http://www.effectiveperlprogramming.com/wp-content/plugins/tweet-this/icons/tt-digg.png" alt="Post to Digg" /></a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/1345&amp;title=Enchant+closures+for+better+debugging+output" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/1345&amp;t=Enchant+closures+for+better+debugging+output" title="Post to Facebook"><img class="nothumb" src="http://www.effectiveperlprogramming.com/wp-content/plugins/tweet-this/icons/tt-facebook.png" alt="Post to Facebook" /></a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/1345&amp;t=Enchant+closures+for+better+debugging+output" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/1345&amp;title=Enchant+closures+for+better+debugging+output" title="Post to Reddit"><img class="nothumb" src="http://www.effectiveperlprogramming.com/wp-content/plugins/tweet-this/icons/tt-reddit.png" alt="Post to Reddit" /></a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/1345&amp;title=Enchant+closures+for+better+debugging+output" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/1345/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Use scalar references to pass large data without copying.</title>
		<link>http://www.effectiveperlprogramming.com/blog/298</link>
		<comments>http://www.effectiveperlprogramming.com/blog/298#comments</comments>
		<pubDate>Sun, 30 May 2010 02:02:09 +0000</pubDate>
		<dc:creator>brian d foy</dc:creator>
				<category><![CDATA[item]]></category>
		<category><![CDATA[references]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=298</guid>
		<description><![CDATA[References aren&#8217;t just for data structures, and many people overlook the benefit of references to simple scalars. With references to arrays and hashes you can keep those data structures in tact when you pass them to or return them from subroutines (Item 46: Pass references instead of copies). You don&#8217;t need to worry about scalar [...]]]></description>
			<content:encoded><![CDATA[<p>References aren&#8217;t just for data structures, and many people overlook the benefit of references to simple scalars. With references to arrays and hashes you can keep those data structures in tact when you pass them to or return them from subroutines (<span class="item">Item 46: Pass references instead of copies</span>). You don&#8217;t need to worry about scalar values because they are a single item in both the non-reference and reference form.</p>
<p>The benefit of a scalar reference comes when you realize that perl is stack-based. That is, when it wants to pass things to a subroutine, it puts things on a stack and calls the subroutine. The subroutine takes the right number of things off the stack, does its processing, and puts its return values on the stack. The caller takes the return values off the stack and the program continues. Moving those data onto and off the stack can involve quite a bit of copying.</p>
<p>When you call a subroutine, <code>perl</code> really only puts pointers to the data on the stack. These aren&#8217;t pointers in the C sense, but we use the word to distinguish it from Perl&#8217;s specialized definition of &#8220;reference&#8221;. It&#8217;s not until you want to assign the values to variables that perl has to copy the original data to initialize the new variables. This lazy initialization is a performance optimization perl uses to avoid copying data it doesn&#8217;t need to. When you unpack your argument list into variables, you copy the data into the variable. </p>
<p>Here&#8217;s a sequence of events that shows that you make several copies of the same data when you pass a string as an argument, store it in a temporary variable, and then return the unchanged string. This example uses a short string of <code>abc</code> replicated 10 times, but imagine this to be a large XML document or something similarly daunting:</p>
<pre class="brush:perl">
use Devel::Peek;
use 5.010;

my $old_version = 'abc' x 10;
say Dump( $old_version );

my $new_version = copy_string( $old_version );
say Dump( $new_version );

sub copy_string {
	my( $copy ) = @_;
	say Dump( $copy );
	$copy;
	}
</pre>
<p>The output shows that you made three different copies of the same data, one each for the original, the temporary variable in the subroutine, and the return value. It&#8217;s the address after <code>PV = </code> and right before the string that shows the location of the data (rather than the location of the variable). In this case, those addresses are <code>0x219490</code>, <code>0x2194b0</code>, and <code>0x219430</code>:</p>
<pre class="brush:plain">
SV = PV(0x801080) at 0x80f680
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x219490 "abcabcabcabcabcabcabcabcabcabc"\0
  CUR = 30
  LEN = 32

SV = PV(0x801028) at 0x81b3d0
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x2194b0 "abcabcabcabcabcabcabcabcabcabc"\0
  CUR = 30
  LEN = 32

SV = PV(0x8015f8) at 0x80f670
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x219430 "abcabcabcabcabcabcabcabcabcabc"\0
  CUR = 30
  LEN = 32
</pre>
<p>There&#8217;s a way, not necessarily a best practice, that people use to get around that first copy. When you use <code>@_</code> directly, you use and affect the original data because you actually use the original data instead of a copy of it. That&#8217;s why you sometimes see people use it directly in subroutines to change data in place:</p>
<pre class="brush:perl">
use Devel::Peek;
use 5.010;

my $old_version = 'abc' x 10;
say Dump( $old_version );

my $new_version = copy_string( $old_version );
say Dump( $new_version );

sub copy_string {
	say Dump( $_[0] );
	$_[0];
	}
</pre>
<p>However, since <code>copy_string</code> modifies its argument in-place, you don&#8217;t need the return value.</p>
<pre class="brush:perl">
use Devel::Peek;
use 5.010;

my $old_version = 'abc' x 10;
say Dump( $old_version );

copy_string( $old_version );

sub copy_string {
	say Dump( $_[0] );
	$_[0];
	}
</pre>
<p>Now the output shows that <code>$old_version</code> and <code>$_[0]</code> are the same data (just not equivalent strings). Notice that the address of the two variables (<code>0x801080</code> in this case) are the same. That&#8217;s the special aliasing magic:</p>
<pre class="brush:plain">
SV = PV(0x801080) at 0x80f680
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x219440 "abcabcabcabcabcabcabcabcabcabc"\0
  CUR = 30
  LEN = 32

SV = PV(0x801080) at 0x80f680
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x219440 "abcabcabcabcabcabcabcabcabcabc"\0
  CUR = 30
  LEN = 32
</pre>
<p>Using <code>@_</code> directly might be fine for very light jobs, but what if the argument list is more complicated? You don&#8217;t want track the position of the argument in <code>@_</code>.</p>
<p>Instead, you use a scalar reference. The argument list contains a real Perl reference, so you aren&#8217;t copying anything other than the connection to the data.<br />
You can store the reference value in a named variable without making a copy of the end values:</p>
<pre class="brush:perl">
use Devel::Peek;
use 5.010;

my $old_version = 'abc' x 10;
say Dump( $old_version );

my $new_version = copy_string( \$old_version );

sub copy_string {
	my( $ref ) = @_;
	say Dump( $$ref ); # deref to see data, not ref to it
	}
</pre>
<p>The output shows essentially the same effect as using <code>@_</code> directly:</p>
<pre class="brush:plain">
SV = PV(0x801080) at 0x80f680
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x2042f0 "abcabcabcabcabcabcabcabcabcabc"\0
  CUR = 30
  LEN = 32

SV = PV(0x801080) at 0x80f680
  REFCNT = 3
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x2042f0 "abcabcabcabcabcabcabcabcabcabc"\0
  CUR = 30
  LEN = 32
</pre>
<p>The advantage with a reference is that you won&#8217;t unintentionally make a copy when you store the value in a variable. Say, for instance, that you need to call another subroutine and pass along one of the arguments, and that second subroutine store it in a temporary variable:</p>
<pre class="brush:perl">
use Devel::Peek;
use 5.010;

my $old_version = 'abc' x 10;
say Dump( $old_version );

copy_string( $old_version );

sub copy_string {
	say Dump( $_[0] );
	another_sub( $_[0] );
	}

sub another_sub {
	my( $string ) = @_;
	say Dump( $string );
	}
</pre>
<p>Now you&#8217;ve made a copy of the data in <code>another_sub</code>:</p>
<pre class="brush:plain">
SV = PV(0x801080) at 0x80f680
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x21d250 "abcabcabcabcabcabcabcabcabcabc"\0
  CUR = 30
  LEN = 32

SV = PV(0x801080) at 0x80f680
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x21d250 "abcabcabcabcabcabcabcabcabcabc"\0
  CUR = 30
  LEN = 32

SV = PV(0x801028) at 0x81b4e0
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x204340 "abcabcabcabcabcabcabcabcabcabc"\0
  CUR = 30
  LEN = 32
</pre>
<p>If you passed along references instead, it&#8217;s always the same reference so there&#8217;s no danger of creating another copy:</p>
<pre class="brush:perl">
use Devel::Peek;
use 5.010;

my $old_version = 'abc' x 10;
say Dump( $old_version );

copy_string( \ $old_version );

sub copy_string {
	my( $ref ) = @_;
	say Dump( $$ref );
	another_sub( $ref );
	}

sub another_sub {
	my( $ref ) = @_;
	say Dump( $$ref );
	}
</pre>
<p>The output shows only one copy, even though you used two different temporary variables:</p>
<pre class="brush:plain">
SV = PV(0x801080) at 0x80f680
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x219350 "abcabcabcabcabcabcabcabcabcabc"\0
  CUR = 30
  LEN = 32

SV = PV(0x801080) at 0x80f680
  REFCNT = 3
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x219350 "abcabcabcabcabcabcabcabcabcabc"\0
  CUR = 30
  LEN = 32

SV = PV(0x801080) at 0x80f680
  REFCNT = 4
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x219350 "abcabcabcabcabcabcabcabcabcabc"\0
  CUR = 30
  LEN = 32
</pre>
<h2>Things to remember</h2>
<ul>
<li><code>perl</code> makes copies of data when you assign it to different variables.
<li>Pass scalar references as arguments to avoid unnecessary string duplications.
<li>You can modify variables in-place through references.
</ul>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Use+scalar+references+to+pass+large+data+without+copying.+http://tinyurl.com/6lcrvjd" title="Post to Twitter"><img class="nothumb" src="http://www.effectiveperlprogramming.com/wp-content/plugins/tweet-this/icons/tt-twitter2.png" alt="Post to Twitter" /></a> <a class="tt" href="http://twitter.com/home/?status=Use+scalar+references+to+pass+large+data+without+copying.+http://tinyurl.com/6lcrvjd" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/298&amp;title=Use+scalar+references+to+pass+large+data+without+copying." title="Post to Delicious"><img class="nothumb" src="http://www.effectiveperlprogramming.com/wp-content/plugins/tweet-this/icons/tt-delicious.png" alt="Post to Delicious" /></a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/298&amp;title=Use+scalar+references+to+pass+large+data+without+copying." title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/298&amp;title=Use+scalar+references+to+pass+large+data+without+copying." title="Post to Digg"><img class="nothumb" src="http://www.effectiveperlprogramming.com/wp-content/plugins/tweet-this/icons/tt-digg.png" alt="Post to Digg" /></a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/298&amp;title=Use+scalar+references+to+pass+large+data+without+copying." title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/298&amp;t=Use+scalar+references+to+pass+large+data+without+copying." title="Post to Facebook"><img class="nothumb" src="http://www.effectiveperlprogramming.com/wp-content/plugins/tweet-this/icons/tt-facebook.png" alt="Post to Facebook" /></a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/298&amp;t=Use+scalar+references+to+pass+large+data+without+copying." title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/298&amp;title=Use+scalar+references+to+pass+large+data+without+copying." title="Post to Reddit"><img class="nothumb" src="http://www.effectiveperlprogramming.com/wp-content/plugins/tweet-this/icons/tt-reddit.png" alt="Post to Reddit" /></a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/298&amp;title=Use+scalar+references+to+pass+large+data+without+copying." title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/298/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Make deep copies</title>
		<link>http://www.effectiveperlprogramming.com/blog/85</link>
		<comments>http://www.effectiveperlprogramming.com/blog/85#comments</comments>
		<pubDate>Sun, 21 Mar 2010 10:58:24 +0000</pubDate>
		<dc:creator>brian d foy</dc:creator>
				<category><![CDATA[item]]></category>
		<category><![CDATA[references]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=85</guid>
		<description><![CDATA[When you want to make a copy of a hash or an array, it&#8217;s not enough to merely assign it to a new variable name, at least in the general case: my @copy = @original; This is a bad habit that new Perl programmers pick up because they are only dealing with flat arrays: that [...]]]></description>
			<content:encoded><![CDATA[<p>
When you want to make a copy of a hash or an array, it&#8217;s not enough to merely assign it to a new variable name, at least in the general case:
</p>
<pre class="brush:perl">
my @copy = @original;
</pre>
<p>
This is a bad habit that new Perl programmers pick up because they are only dealing with <i>flat arrays</i>: that is, every value is a simple scalar, so they never see the problem:
</p>
<pre class="brush:perl">
my @original = qw( Buster Ginger Mimi Ella );

my @copy     = @original;
</pre>
<p>
If you know that you have only a flat array, that&#8217;s not a problem. However, the experienced programmer knows that &#8220;you know&#8221; is often the source of misguided assumptions that blow up later.
</p>
<p>
At the <A href=http://oreilly.com/catalog/9780596520113"">Learning Perl</a> level, we conveniently skirt the issue because we don&#8217;t talk about references until <a href="http://oreilly.com/catalog/9780596102067">Intermediate Perl</a>. That&#8217;s right: blame me.
</p>
<p>
Consider the case where one of the array elements is a reference. As long as you don&#8217;t change the values, you don&#8217;t see the problem:
</p>
<pre class="brush:perl">
my $buster      = {
	name => 'Buster',
	colors => [ qw(black white) ]
	};
my @original = ( $buster, qw( Ginger Mimi Ella ) );

my @copy     = @original;

printf "In \@original, the first cat's name is %s\n", $original[0]->{name};
printf "In \@copy, the first cat's name is %s\n", $copy[0]->{name};
</pre>
<p>
The output doesn&#8217;t show anything out of place:
</p>
<pre class="brush:plain">
In @original, the first cat's name is Buster
In @copy, the first cat's name is Buster
</pre>
<p>
Now change one of the values in <code>@copy</code>:
</p>
<pre class="brush:perl">
my $buster      = {
	name => 'Buster',
	colors => [ qw(black white) ]
	};
my @original = ( $buster, qw( Ginger Mimi Ella ) );

my @copy     = @original;

$copy[0]->{name} = 'Roscoe';

printf "In \@original, the first cat's name is %s\n", $original[0]->{name};
printf "In \@copy, the first cat's name is %s\n", $copy[0]->{name};
</pre>
<p>
The output now shows both arrays were affected even though you only wanted to change <code>@copy</code>:
</p>
<pre class="brush:plain">
In @original, the first cat's name is Roscoe
In @copy, the first cat's name is Roscoe
</pre>
<p>
Instead of an assignment, which is the source of your problem, make a <i>deep copy</i>. There are several ways that you can do this. The <code>dclone</code><br />
function (for <bold>d<bold>eep clone) from <a href="http://search.cpan.org/dist/Storable/">Storable</a> (part of the Standard Library) can do it for you:
</p>
<pre class="brush:plain">
use Storable qw(dclone);

my $buster      = {
	name => 'Buster',
	colors => [ qw(black white) ]
	};
my @original = ( $buster, qw( Ginger Mimi Ella ) );

my $copy     = dclone \@original;

$copy->[0]{name} = 'Roscoe';

printf "In \@original, the first cat's name is %s\n", $original[0]->{name};
printf "In \@copy, the first cat's name is %s\n", $copy->[0]{name};
</pre>
<p>
Now the output shows that the two arrays remained distinct:
</p>
<pre class="brush:plain">
In @original, the first cat's name is Buster
In @copy, the first cat's name is Roscoe
</pre>
<p>
You had to make one subtle change to your program, however. <code>dclone</code> takes a reference and returns a reference, so you didn&#8217;t copy <code>@original</code> to another array variable. That&#8217;s not very nice. You could copy the de-referenced value:
</p>
<pre class="brush:plain">
my @copy     = @{ dclone \@original };
</pre>
<p>
That&#8217;s not very pretty either. You could hide that in a subroutine, but the easiest thing is to just give over to references and use them everywhere from the start (but that&#8217;s another Item for another time):
</p>
<pre class="brush:plain">
use Storable qw(dclone);

my $buster      = {
	name => 'Buster',
	colors => [ qw(black white) ]
	};
my $original = [ $buster, qw( Ginger Mimi Ella ) ];

my $copy     = dclone $original;

$copy->[0]{name} = 'Roscoe';

printf "In \$original, the first cat's name is %s\n", $original->[0]{name};
printf "In \$copy, the first cat's name is %s\n", $copy->[0]{name};
</pre>
<p>
Set aside the issue named variables to consider a more common case where that reference element in your array is an object. Here&#8217;s the simple class that implements a simple Cat:
</p>
<pre class="brush:perl">
BEGIN {
package Cat;

sub new {
	my( $class, %hash ) = @_;
	bless \%hash, $class;
	}

sub set_name { $_[0]->{name} = $_[1] }
sub get_name { $_[0]->{name} }
}
</pre>
<p>
Converting your previous problematic program to use <code>Cat</code>, you have:
</p>
<pre class="brush:perl">
my $buster      = Cat->new(
	name => 'Buster',
	colors => [ qw(black white) ]
	);
my $original = [ $buster, qw( Ginger Mimi Ella ) ];

my $copy     = $original;

$copy->[0]->set_name( 'Roscoe' );

printf "In \$original, the first cat's name is %s\n", $original->[0]->get_name;
printf "In \$copy, the first cat's name is %s\n", $copy->[0]->get_name;
</pre>
<p>
Again, the output shows that you changed &#8220;both&#8221; objects:
</p>
<pre class="brush:plain">
In $original, the first cat's name is Roscoe
In $copy, the first cat's name is Roscoe
</pre>
<p>
Using <code>dclone</code> solves the problem:
</p>
<pre class="brush:perl">
my $buster      = Cat->new(
	name => 'Buster',
	colors => [ qw(black white) ]
	);
my $original = [ $buster, qw( Ginger Mimi Ella ) ];

my $copy     = dclone $original;

$copy->[0]->set_name( 'Roscoe' );

printf "In \$original, the first cat's name is %s\n", $original->[0]->get_name;
printf "In \$copy, the first cat's name is %s\n", $copy->[0]->get_name;
</pre>
<p>
Now you have two separate objects, each with distinct values:
</p>
<pre class="brush:plain">
In $original, the first cat's name is Buster
In $copy, the first cat's name is Roscoe
</pre>
<p>
There&#8217;s an additional problem here though. Simply cloning an object might not be the right thing. What if the object has database connections, open filehandles, or other bits that should be properly re-initialized? What if the object is actually a singleton, so you end up with a copy anyway? You can add a <code>clone</code> method to your class to handle that, and we&#8217;ll cover that in a later Item.</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Make+deep+copies+http://tinyurl.com/yj2gryl" title="Post to Twitter"><img class="nothumb" src="http://www.effectiveperlprogramming.com/wp-content/plugins/tweet-this/icons/tt-twitter2.png" alt="Post to Twitter" /></a> <a class="tt" href="http://twitter.com/home/?status=Make+deep+copies+http://tinyurl.com/yj2gryl" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/85&amp;title=Make+deep+copies" title="Post to Delicious"><img class="nothumb" src="http://www.effectiveperlprogramming.com/wp-content/plugins/tweet-this/icons/tt-delicious.png" alt="Post to Delicious" /></a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/85&amp;title=Make+deep+copies" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/85&amp;title=Make+deep+copies" title="Post to Digg"><img class="nothumb" src="http://www.effectiveperlprogramming.com/wp-content/plugins/tweet-this/icons/tt-digg.png" alt="Post to Digg" /></a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/85&amp;title=Make+deep+copies" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/85&amp;t=Make+deep+copies" title="Post to Facebook"><img class="nothumb" src="http://www.effectiveperlprogramming.com/wp-content/plugins/tweet-this/icons/tt-facebook.png" alt="Post to Facebook" /></a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/85&amp;t=Make+deep+copies" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/85&amp;title=Make+deep+copies" title="Post to Reddit"><img class="nothumb" src="http://www.effectiveperlprogramming.com/wp-content/plugins/tweet-this/icons/tt-reddit.png" alt="Post to Reddit" /></a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/85&amp;title=Make+deep+copies" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/85/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

