<?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</title>
	<atom:link href="http://www.effectiveperlprogramming.com/feed" rel="self" type="application/rss+xml" />
	<link>http://www.effectiveperlprogramming.com</link>
	<description>Effective Perl Programming - write better, more idiomatic Perl</description>
	<lastBuildDate>Mon, 06 Sep 2010 22:49:09 +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>Use branch reset grouping to number captures in alternations</title>
		<link>http://www.effectiveperlprogramming.com/blog/559</link>
		<comments>http://www.effectiveperlprogramming.com/blog/559#comments</comments>
		<pubDate>Sun, 05 Sep 2010 19:19:58 +0000</pubDate>
		<dc:creator>brian d foy</dc:creator>
				<category><![CDATA[5.10]]></category>
		<category><![CDATA[regular expressions]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=559</guid>
		<description><![CDATA[Perl&#8217;s regular expressions have a simple rule for capturing groups. It counts the order of left parentheses to assign capture variables. Not all capture groups must actually match parts of the string, and Perl doesn&#8217;t care if they do. Perl assigns capture groups inside an alternation consecutively, even though it knows that only one branch [...]]]></description>
			<content:encoded><![CDATA[<p>Perl&#8217;s regular expressions have a simple rule for capturing groups. It counts the order of left parentheses to assign capture variables. Not all capture groups must actually match parts of the string, and Perl doesn&#8217;t care if they do. Perl assigns capture groups inside an alternation consecutively, even though it knows that only one branch of the alternation will match. Perl 5.10 adds the branch reset, <code>(?|alternation)</code> which mitigates that, though.</p>
<p>How many captures will a particular pattern produce? Can you tell just by looking at the pattern? How much does the particular string matter? How many capture groups are in this pattern:</p>
<pre class="brush:perl">
(Buster)|(Mimi)|(Ella)
</pre>
<p>There are three capture groups. Only one of them is going to capture because each group is in a different branch of the alternation. What capture variables will that pattern set?</p>
<div align="center">
<table>
<tr>
<th>String</th>
<th>Triggered groups</th>
<th>$1</th>
<th>$2</th>
<th>$3</th>
</tr>
<tr>
<td>Buster</td>
<td>(Buster)</td>
<td>Buster</td>
<td>undef</td>
<td>undef</td>
</tr>
<tr>
<td>Mimi</td>
<td>(Mimi)</td>
<td>undef</td>
<td>Mimi</td>
<td>undef</td>
</tr>
<tr>
<td>Ella</td>
<td>(Ella)</td>
<td>undef</td>
<td>undef</td>
<td>Ella</td>
</tr>
<tr>
<td>Buster Mimi Ella</td>
<td>(Buster)</td>
<td>Buster</td>
<td>undef</td>
<td>undef</td>
</tr>
</table>
</div>
<p>No matter which string you match against this pattern, you&#8217;ll also set at least three of the capture variables, and two of those will be undefined.</p>
<p>Perl 5.10 introduces the <i>branch reset pattern</i>, <code>(?|alternation)</code>. You use that so that Perl numbers the capture buffers from the same starting point for each branch in the alternation. Instead of creating three capture buffers in your alternation, you can create just one buffer for this pattern: </p>
<pre class="brush:perl">
(?|(Buster)|(Mimi)|(Ella))
</pre>
<p>The three capture groups in this pattern populate the same buffer:</p>
<div align="center">
<table>
<tr>
<th>String</th>
<th>Triggered groups</th>
<th>$1</th>
</tr>
<tr>
<td>Buster</td>
<td>(Buster)</td>
<td>Buster</td>
</tr>
<tr>
<td>Mimi</td>
<td>(Mimi)</td>
<td>Mimi</td>
</tr>
<tr>
<td>Ella</td>
<td>(Ella)</td>
<td>Ella</td>
</tr>
<tr>
<td>Buster Mimi Ella</td>
<td>(Buster)</td>
<td>Buster</td>
</tr>
</table>
</div>
<p>This is more important when the alternation is in the middle of a larger pattern and there are additional capture groups after the alternation:</p>
<pre class="brush:perl">
(?|(Buster)|(Mimi)|(Ella))(Ginger)
</pre>
<p>That&#8217;s a bit easier to read with extended patterns (<span class="item">Item 37: Make regular expressions readable</span>):</p>
<pre class="brush:perl">
(?|             # $1
	(Buster) |
	(Mimi)   |
	(Ella)
)
(               # $2
	Ginger
)
</pre>
<p>No matter how many branches you add to the alternation, the group for <code>Ginger</code> is always <code>$2</code>:</p>
<pre class="brush:perl">
(?|             # $1
	(Buster) |
	(Mimi)   |
	(Ella)   |
	(Roscoe)
)
(               # $2
	Ginger
)
</pre>
<p>That doesn&#8217;t mean that the numbering after the alternation is always the same though. Not every branch must have the same number of captures, but the pattern reset grouping always takes up the number of buffers in the branch with the  most capture groups even if that&#8217;s not the branch that matches. Consider this pattern where one of the branches has two capture groups:</p>
<pre class="brush:perl">
(?|
	(Buster)       |  # $1, $2 is undef
	(Mimi)(Roscoe) |  # $1, $2
	(Ella)            # $1, $2 is undef
)
(                     # $3
	Ginger
)
</pre>
<p>The <code>$1</code> variable is always the first capture group of whichever branch matched:</p>
<div align="center">
<table>
<tr>
<th>String</th>
<th>Triggered groups</th>
<th>$1</th>
</tr>
<tr>
<td>BusterGinger</td>
<td>(Buster)</td>
<td>Buster</td>
</tr>
<tr>
<td>MimiRoscoeGinger</td>
<td>(Mimi)</td>
<td>Mimi</td>
</tr>
</table>
</div>
<p>The branch reset can cause problems with named captures (<span class="item">Item 31: Use named captures to label matches</span>), which are really just aliases the the numbered captured variables. Labeling each capture group doesn&#8217;t do what you might expect: </p>
<pre class="brush:perl">
(?|
	(?&lt;cat1>Buster)              |  # $1, $2 is undef
	(?&lt;cat2>Mimi)(?&lt;cat3>Roscoe) |  # $1, $2
	(?&lt;cat4>Ella)                   # $1, $2 is undef
)
(?&lt;cat5>
	Ginger
)
</pre>
<p>Each label is just an alias to its numbered capture variable:</p>
<div align="center">
<table>
<tr>
<th>Label</th>
<th>Aliased to</th>
</tr>
<tr>
<td>cat1</td>
<td>$1</td>
</tr>
<tr>
<td>cat2</td>
<td>$1</td>
</tr>
<tr>
<td>cat3</td>
<td>$2</td>
</tr>
<tr>
<td>cat4</td>
<td>$1</td>
</tr>
<tr>
<td>cat5</td>
<td>$3</td>
</tr>
</table>
</div>
<p>The labels don&#8217;t apply to the groups you think they do: </p>
<div align="center">
<table>
<tr>
<th>String</th>
<th>$1</th>
<th>$2</th>
<th>cat1</th>
<th>cat2</th>
<th>cat3</th>
<th>cat4</th>
</tr>
<tr>
<td>BusterGinger</td>
<td>Buster</td>
<td>undef</td>
<td>Buster</td>
<td>Buster</td>
<td>undef</td>
<td>Buster</td>
</tr>
<tr>
<td>EllaGinger</td>
<td>Ella</td>
<td>undef</td>
<td>Ella</td>
<td>Ella</td>
<td>undef</td>
<td>Ella</td>
</tr>
<tr>
<td>MimiRoscoeGinger</td>
<td>Mimi</td>
<td>Roscoe</td>
<td>Mimi</td>
<td>Mimi</td>
<td>Roscoe</td>
<td>Mimi</td>
</tr>
</table>
</div>
<p>You should probably use the same labels in each branch and order them the same so you get the results that you expect:</p>
<pre class="brush:perl">
(?|
	(?&lt;cat1>Buster)              |  # $1, $2 is undef
	(?&lt;cat1>Mimi)(?&lt;cat2>Roscoe) |  # $1, $2
	(?&lt;cat1>Ella)                   # $1, $2 is undef
)
(?&lt;cat3>
	Ginger
)
</pre>
<h2>Things to remember</h2>
<ul>
<li>Perl numbers capture groups by counting the literal order of left parentheses
<li>Every capture group in an alternation creates a capture buffer
<li>The pattern reset grouping, <code>(?|...)</code> restarts the buffer numbering for each branch of the alternation
<li>Label captures in alternations with the same labels in the same order
</ul>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Use+branch+reset+grouping+to+number+captures+in+alternations+http://q4f79.th8.us" 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+branch+reset+grouping+to+number+captures+in+alternations+http://q4f79.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/559&amp;title=Use+branch+reset+grouping+to+number+captures+in+alternations" 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/559&amp;title=Use+branch+reset+grouping+to+number+captures+in+alternations" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/559&amp;title=Use+branch+reset+grouping+to+number+captures+in+alternations" 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/559&amp;title=Use+branch+reset+grouping+to+number+captures+in+alternations" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/559&amp;t=Use+branch+reset+grouping+to+number+captures+in+alternations" 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/559&amp;t=Use+branch+reset+grouping+to+number+captures+in+alternations" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/559&amp;title=Use+branch+reset+grouping+to+number+captures+in+alternations" 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/559&amp;title=Use+branch+reset+grouping+to+number+captures+in+alternations" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/559/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Use when() as a statement modifier</title>
		<link>http://www.effectiveperlprogramming.com/blog/543</link>
		<comments>http://www.effectiveperlprogramming.com/blog/543#comments</comments>
		<pubDate>Mon, 30 Aug 2010 05:40:26 +0000</pubDate>
		<dc:creator>brian d foy</dc:creator>
				<category><![CDATA[5.12]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=543</guid>
		<description><![CDATA[Perl 5.10 introduced the given-when statement, and Perl 5.12 refines it slightly by letting you use the when as a statement modifier. A statement modifier puts the conditional expression at the end of the statement (see perlsyn). You&#8217;ve probably already used many of these: print "It's too darned hot!\n" if $city eq 'Baltimore'; print "I'm [...]]]></description>
			<content:encoded><![CDATA[<p>Perl 5.10 introduced the <code>given-when</code> statement, and Perl 5.12 refines it slightly by letting you use the <code>when</code> as a statement modifier.</p>
<p>A statement modifier puts the conditional expression at the end of the statement (see <a href="http://perldoc.perl.org/perlsyn.html">perlsyn</a>). You&#8217;ve probably already used many of these:</p>
<pre class="brush:perl">
print "It's too darned hot!\n" if $city eq 'Baltimore';
print "I'm this far!\n" unless $Quiet;
print "An element is $_.\n" foreach @array;
print "Found cat at @{[pos]}\n" while /cat/g;
do { $count++; $i_am_bored = int rand 2 } until $i_am_bored;
</pre>
<p>In Perl 5.10, you have to put the <code>when</code> first, put parentheses around the conditional expression, and follow it with a block:</p>
<pre class="brush:perl">
use 5.012;

my %microchips = (
	  'Mimi'   => 123,
	  'Buster' => undef,
	  'Roscoe' => 345,
	);
my @array = ( 5 .. 7 );

foreach ( 1 .. 10, qw(Mimi Buster) ) {
	when( @array )      { say "$_: in array" }
	when( %microchips ) { say "$_: in hash"  }
	}
</pre>
<p>Perl 5.12 allows you to use the <code>when</code> as a statement modifier instead, which means that you can put the <code>when</code> after the expression that you want to run:</p>
<pre class="brush:perl">
use 5.012;

...;

foreach ( 1 .. 10, qw(Mimi Buster) ) {
	say "$_: in array" when( @array );
	say "$_: in hash"  when( %microchips );
	}
</pre>
<p>Just like you can with the other statement modifiers, you can omit the parentheses around the condition:</p>
<pre class="brush:perl">
use 5.012;

...;

foreach ( 1 .. 10, qw(Mimi Buster) ) {
	say "$_: in array" when @array;
	say "$_: in hash"  when %microchips;
	}
</pre>
<p>As a statement modifier, the expression before the <code>when</code> has an implicit <code>break</code> when you use it with <code>given</code> or an implicit <code>next</code> when you use it with <code>foreach</code>. That is, once a <code>when</code> condition evaluates to true, Perl doesn&#8217;t continue with the rest of the block. </p>
<p>The <code>foreach</code> case actually looks like this:</p>
<pre class="brush:perl">
use 5.012;

...;

foreach ( 1 .. 10, qw(Mimi Buster) ) {
	do { say "$_: in array"; next } when @array;
	do { say "$_: in hash";  next } when %microchips;
	}
</pre>
<p>And the <code>given</code> case actually looks like:</p>
<pre class="brush:perl">
use 5.012;

...;

given ( $cat ) {
	do { say "$_: in array"; break } when @array;
	do { say "$_: in hash";  break } when %microchips;
	}
</pre>
<p>You&#8217;re still supposed to use <code>when</code> inside a topicalizer (e.g. <code>foreach</code> or <code>given</code>). You might be tempted to use it more liberally so you can take advantage of its implicit smart matching anywhere that you like. A curious and perhaps unintended parsing makes it a runtime error instead of a compilation error:</p>
<pre class="brush:perl">
use 5.012;

my %microchips = (
	  'Mimi'   => 123,
	  'Buster' => undef,
	  'Roscoe' => 345,
	);

while( &lt;STDIN&gt; ) {
	chomp;
	# this works (without a warning) as long as the value in $_
	# is not a hash key
	say "Found cat with id [$microchips{$_}]" when %microchips;
	}
</pre>
<p>The <code>while</code> isn&#8217;t a topicalizer, even though in this particular idiom it sets <code>$_</code> for you. You get the output along with a warning:</p>
<pre class="brush:plain">
$ perl5.12.1 no-topicalizer.pl
Buster
Found cat with id []
Can't use when() outside a topicalizer at test line 11, &lt;STDIN&gt; line 1.
</pre>
<p>However, you don&#8217;t get a fatal error when the condition is false, which is probably another bug (filed as <a href="http://rt.perl.org/rt3/Ticket/Display.html?id=77510">RT #77510</a>). There&#8217;s no fatal error, no warning message, and the output shows that Perl kept going:</p>
<pre class="brush:plain">
Ella
Mimi
Found cat with id 123
Can't use when() outside a topicalizer at test line 11, &lt;STDIN&gt; line 2.
</pre>
<p>Just because it it does just what you think it should do then dies telling you it doesn&#8217;t do that, don&#8217;t think you should do it. You could use <code>eval</code> to catch the fatal error, but that&#8217;s a kludge that will only work until the Perl developers fix the problem. Besides, if you are going to go that far, it&#8217;s just as easy to make the smart match explicit with an <code>if</code> statement modifier (and that is even backward compatible with 5.10):</p>
<pre class="brush:perl">
use 5.010;

my %microchips = (
	  'Mimi'   => 123,
	  'Buster' => undef,
	  'Roscoe' => 345,
	);

while( &lt;STDIN&gt; ) {
	chomp;
	say "Found cat with id $microchips{$_}" if $_ ~~ %microchips;
	}
</pre>
<p>The only question now is how long you will be able to use this before your <a href="http://search.cpan.org/dist/Perl-Critic">Perl::Critic</a> policies update to forbid it, whether inside or outside of a topicalizer. Use it while you can: time is running out.</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Use+when%28%29+as+a+statement+modifier+http://p64x5.th8.us" 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+when%28%29+as+a+statement+modifier+http://p64x5.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/543&amp;title=Use+when%28%29+as+a+statement+modifier" 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/543&amp;title=Use+when%28%29+as+a+statement+modifier" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/543&amp;title=Use+when%28%29+as+a+statement+modifier" 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/543&amp;title=Use+when%28%29+as+a+statement+modifier" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/543&amp;t=Use+when%28%29+as+a+statement+modifier" 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/543&amp;t=Use+when%28%29+as+a+statement+modifier" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/543&amp;title=Use+when%28%29+as+a+statement+modifier" 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/543&amp;title=Use+when%28%29+as+a+statement+modifier" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/543/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Perl 5.14 Items coming soon</title>
		<link>http://www.effectiveperlprogramming.com/blog/531</link>
		<comments>http://www.effectiveperlprogramming.com/blog/531#comments</comments>
		<pubDate>Fri, 27 Aug 2010 21:13:12 +0000</pubDate>
		<dc:creator>brian d foy</dc:creator>
				<category><![CDATA[5.14]]></category>
		<category><![CDATA[administrative note]]></category>
		<category><![CDATA[new features]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=531</guid>
		<description><![CDATA[The Perl 5 Porters are currently working on Perl 5.13, the development track that will end up as Perl 5.14. By reading the perldelta513* documentation, you can get a peek at what will mostly likely be in the next maintenance version of Perl. You need to read each of the perldelta5* in a development series [...]]]></description>
			<content:encoded><![CDATA[<p>The Perl 5 Porters are currently working on Perl 5.13, the development track that will end up as Perl 5.14. By reading the <i>perldelta513*</i> documentation, you can get a peek at what will mostly likely be in the next maintenance version of Perl. You need to read each of the <i>perldelta5*</i> in a development series because they only document the changes in to the previous development release, not the cumulative changes since the last major release.</p>
<p>Some things you&#8217;ll find include: </p>
<ul>
<li>A non-destructive substitution with the <code>/r</code> flag: <code>s///r</code>
<li>New ways to specify binary, octal, and hexadecimal numbers.
<li><code>given</code> returns its last evaluated expression (like <code>if-elsif</code> already does).
<li><code>srand</code> returns its seed so you can reuse it.
</ul>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Perl+5.14+Items+coming+soon+http://57awp.th8.us" 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=Perl+5.14+Items+coming+soon+http://57awp.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/531&amp;title=Perl+5.14+Items+coming+soon" 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/531&amp;title=Perl+5.14+Items+coming+soon" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/531&amp;title=Perl+5.14+Items+coming+soon" 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/531&amp;title=Perl+5.14+Items+coming+soon" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/531&amp;t=Perl+5.14+Items+coming+soon" 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/531&amp;t=Perl+5.14+Items+coming+soon" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/531&amp;title=Perl+5.14+Items+coming+soon" 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/531&amp;title=Perl+5.14+Items+coming+soon" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/531/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Use formats to create paginated, plaintext reports</title>
		<link>http://www.effectiveperlprogramming.com/blog/523</link>
		<comments>http://www.effectiveperlprogramming.com/blog/523#comments</comments>
		<pubDate>Sun, 22 Aug 2010 18:44:55 +0000</pubDate>
		<dc:creator>brian d foy</dc:creator>
				<category><![CDATA[formats]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=523</guid>
		<description><![CDATA[Perl&#8217;s format feature allows you to easily create line-oriented text reports with pagination, and if that&#8217;s what you want, Perl is for you. This item is just an introduction. You can find the full details in perlform, and in future items. You may have never heard of formats, but, believe it or not, they were [...]]]></description>
			<content:encoded><![CDATA[<p>Perl&#8217;s format feature allows you to easily create line-oriented text reports with pagination, and if that&#8217;s what you want, Perl is for you. This item is just an introduction. You can find the full details in <a href="http://perldoc.perl.org/perlform.html">perlform</a>, and in future items.</p>
<p>You may have never heard of formats, but, believe it or not, they were an exciting feature 20 years ago. <a href="http://oreilly.com/catalog/1565920422">Learning Perl, First Edition</a> had an entire chapter on them, but that chapter disappeared in the <a href="http://oreilly.com/catalog/9780596001322">Learning Perl, Third Edition</a>, cutting formats out of this millineum. Formats might not be the new black, but they do have some class in an old-school sorta way.</p>
<p>Formats provide some attractive features:</p>
<ul>
<li>Automatic pagination and page numbering
<li>Nice columnar output formatting
<li>Easily lining up decimal points in numbers
</ul>
<p>You could handle all of this yourself, but why would you want to if formats can already do it for you? You can get close with <a href="http://perldoc.perl.org/functions/pack.html">pack</a> or <a href="http://perldoc.perl.org/functions/format.html">printf</a>, but you have to do a lot of extra work that formats already do.</p>
<p>There is a modular version of formats in <a href="http://search.cpan.org/dist/Perl6-Form">Perl6::Form</a>. Indeed, one of the first reactions to Perl 6 was &#8220;You better not take away my formats!&#8221; to which Damian replied  in <a href="http://dev.perl.org/perl6/doc/design/exe/E07.html">Exegesis 7</a> &#8220;We&#8217;re not taking them away, just moving them to a module. Oh, and I&#8217;m making them even cooler!&#8221;. Or something like that. It was several years ago, you have to realize. </p>
<p>That doesn&#8217;t mean that Perl 5 formats are useless today. If you want to output palintext lists, as in actually put ink on paper, perhaps so you can take an inventory all of the cats in your house, then formats are quite useful. In this Item, you&#8217;ll create output that looks like:</p>
<pre class="brush:plain">
Household Pet Inventory, Page  1

 ID   NAME          DIET            OUNCES
--------------------------------------------
 12   Buster        Tuna            1.00
  1   Mimi          Pounces         0.30
 37   Ginger        Fancy Feast     0.75
 19   Ellie         White Castle    9.99
</pre>
<p>First, you have to define the formats themselves. These are somewhat like named subroutine definitions in that they can appear anywhere in the file and are defined at compile time. Every format definition is at least three lines. In the first line, you use the <a href="http://perldoc.perl.org/functions/format.html">format</a> keyword, an identifier (which is conventionally all uppercase since formats have no sigil of their own), and an <code>=</code>. The middle lines, which you&#8217;ll see in a moment, are the <i>form lines</i>. Finally, you end the definition with a literal full stop, <code>.</code>, that has to be on the line by itself and at the beginning of the line:</p>
<pre class="brush:perl">
format STDOUT =
... form lines goes here ...
.
</pre>
<p>The form lines have two parts, the <i>picture</i> lines, and the variables holding the values for the pictures. The pictures are quite sophisticated, like <a href="http://perldoc.perl.org/functions/printf.html">printf</a>, which knows what sort of value it expects, but with the extra formatting. You&#8217;ll only see some of the simple pictures in this Item. Most picture fields will start with a <code>@</code> to denote the start of the picture then have other characters to denote what sort of picture it is:</p>
<div align="center">
<table cellpadding="10">
<tr>
<td bgcolor="yellow">Picture</td>
<td bgcolor="yellow">Meaning</td>
</tr>
<tr>
<td>@<<<<<<</td>
<td>left justified text</td>
</tr>
<tr>
<td>@>>>>>></td>
<td>right justified text</td>
</tr>
<tr>
<td>@||||||</td>
<td>centered text</td>
</tr>
<tr>
<td>@##.##</td>
<td>A number with a decimal point, aligning on the decimal point</td>
</tr>
</table>
</div>
<p>After each picture line, you specify variables whose values will fill in the pictures in the previous form line. You specify the variables in the same order as the picture fields, and you separate the variables in commas. You can put the variable anywhere you like in the line (as long as its in the right order), so you can line them up with their pictures. A simple, format, then looks like this:</p>
<pre class="brush:perl">
format STDOUT =
@##   @<<<<<<<<<    @<<<<<<<<<<<    @#.##
$id,  $name,        $food,          $amount
.
</pre>
<p>As designed, the format name matches the bareword filehandle you'll use it with (but more on that later). You name the format <code>STDOUT</code> because you want to use it with the standard output file handle.</p>
<p>When you are ready to output some data, you use <a href="http://perldoc.perl.org/functions/write.html">write</a>. This design shows the age of formats since <a href="http://perldoc.perl.org/functions/write.html">write</a> doesn't take arguments to fill in the pictures. It uses the variables that are in scope. The argument it does take, however, is the filehandle you want to <a href="http://perldoc.perl.org/functions/write.html">write</a> to:</p>
<pre class="brush:perl">
our( $id, $name, $food, $amount ) = qw( 12 Buster Tuna 1.0 );
write();
</pre>
<p>If you don't specify a filehandle, <a href="http://perldoc.perl.org/functions/write.html">write</a> uses the current default filehandle. Putting that all together, you have:</p>
<pre class="brush:perl">
use strict;
use warnings;

our( $id, $name, $food, $amount ) = qw( 12 Buster Tuna 1.0 );
write();

format STDOUT =
@##   @<<<<<<<<<    @<<<<<<<<<<<    @#.##
$id,  $name,        $food,          $amount
.
</pre>
<p>When you run this starter program, you get a single line of output:</p>
<pre class="brush:plain">
 12   Buster        Tuna             1.00
</pre>
<p>That's fine, but you probably want to know what those columns are. There's a special format for that, too. By appending <code>_TOP</code> to the end of the format name, Perl knows to add a header when it starts a new page. This top-of-page format is like the previous format:</p>
<pre class="brush:perl">
#!perl
use strict;
use warnings;

our( $id, $name, $food, $amount ) = qw( 12 Buster Tuna 1.0 );
write();

format STDOUT =
@##   @<<<<<<<<<    @<<<<<<<<<<<    @#.##
$id,  $name,        $food,          $amount
.

format STDOUT_TOP =
 ID   NAME          DIET            OUNCES
--------------------------------------------
.
</pre>
<p>Now your report comes out with column headers:</p>
<pre class="brush:perl">
 ID   NAME          DIET            OUNCES
--------------------------------------------
 12   Buster        Tuna             1.00
</pre>
<p>Perl's formats are smart enough to know which page of output they are on, and they store that in the <code>$%</code> variable. You can use that to fill in a picture in the top-of-page format:</p>
<pre class="brush:perl">
format STDOUT_TOP =
Household Pet Inventory, Page @#
                              $%

 ID   NAME          DIET            OUNCES
--------------------------------------------
.
</pre>
<p>Now your report has more information at the top, which will appear every time the format starts a new page:</p>
<pre class="brush:plain">
Household Pet Inventory, Page  1

 ID   NAME          DIET            OUNCES
--------------------------------------------
 12   Buster        Tuna             1.00
</pre>
<p>When does a format start a new page, though? The formats know how many lines are in a page. That's in the <code>$=</code> variable, which you can set yourself if you don't want the default 60 lines. The formats are also keeping track of the the number of lines it has output so far. When it reaches the number of lines per page, it outputs a page break to end the page. This is a form feed, so no matter how much physical space you have left on the sheet of paper, your printer should spit it out and move on to the next sheet of paper. The formats then output the top-of-page information and continue where they left off. The <code>\f</code> in this output represents the page break:</p>
<pre class="brush:plain">
Household Pet Inventory, Page  1

 ID   NAME          DIET            OUNCES
--------------------------------------------
 12   Buster        Tuna            1.00
  1   Mimi          Pounces         0.30
....many other lines....

\fHousehold Pet Inventory, Page  2

 ID   NAME          DIET            OUNCES
--------------------------------------------
 78   Roscoe        Turkey babyfood 0.15
</pre>
<h2>Using formats with modern Perl</h2>
<p>Formats are a bit antiquated. They've been a feature since Perl only had bareword filehandles so they look a bit clunky in the world of filehandles stored in variables. By default, formats look for a format name that matches the filehandle you want to <a href="http://perldoc.perl.org/functions/write.html">write</a> to. That is, if you want to send yout output to <code>STDOUT</code>, you name your formats <code>STDOUT</code> and <code>STDOUT_TOP</code>. However, plenty of experienced Perlers will complain when they see you using bareword filehandles. </p>
<p>It's easy to use formats with filehandles you store in scalar variables, though. You just have to tell Perl which format names it should use. As with many things in Perl, you can change special variables to do this. The per-filehandle variables <code>$~</code> and <code>$^</code> hold the names of the format and top-of-page format respectively. As with any of the per-filehandle special variables, each filehandle has their own versions of these and you can only set them on the default filehandle. Thus, you use <a href="http://perldoc.perl.org/functions/select.html">select</a> to change the default filehandle:</p>
<pre class="brush:perl">
open my $fh, '>', $filename or die ...;
{
my $old_default = select( $fh );
$^ = 'CAT_INVENTORY_TOP';
$~ = 'CAT_INVENTORY';
select( $old_default );
}
</pre>
<p>You write to a filehandle by specifying it as an argument:</p>
<pre class="brush:perl">
write( $fh );
</pre>
<p>Formats are also a bit crufty because you don't pass arguments to <a href="http://perldoc.perl.org/functions/write.html">write</a> to fill in the pictures. Perl relies on variables with the specified names being in scope. You can use lexical variables, but they have to be in the same scope as the format definition, and they have to be in scope when you call <a href="http://perldoc.perl.org/functions/write.html">write</a>. It's impractical to do that with lexicals, so the most agile way involves <a href="http://perldoc.perl.org/functions/local.html">local</a>ized package variables:</p>
<pre class="brush:perl">
foreach my $record ( @cats ) {
	local( $id, $name, $food ) = @$record;
	write( $fh );
	}
</pre>
<p>That somewhat mitigates the cruftiness of the format design, and that's about the best that you can do. If formats provide the features you need, however, then its not that annoying to deal with their eccentricities.</p>
<h2>Things to remember</h2>
<ul>
<li>Use formats to create paginated text reports
<li>Set the format names yourself when you use a filehandle in a variable
<li>Use localized package variables to set data for the format
</ul>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Use+formats+to+create+paginated%2C+plaintext+reports+http://nykpp.th8.us" 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+formats+to+create+paginated%2C+plaintext+reports+http://nykpp.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/523&amp;title=Use+formats+to+create+paginated%2C+plaintext+reports" 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/523&amp;title=Use+formats+to+create+paginated%2C+plaintext+reports" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/523&amp;title=Use+formats+to+create+paginated%2C+plaintext+reports" 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/523&amp;title=Use+formats+to+create+paginated%2C+plaintext+reports" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/523&amp;t=Use+formats+to+create+paginated%2C+plaintext+reports" 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/523&amp;t=Use+formats+to+create+paginated%2C+plaintext+reports" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/523&amp;title=Use+formats+to+create+paginated%2C+plaintext+reports" 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/523&amp;title=Use+formats+to+create+paginated%2C+plaintext+reports" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/523/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OpenID Login Now Available</title>
		<link>http://www.effectiveperlprogramming.com/blog/515</link>
		<comments>http://www.effectiveperlprogramming.com/blog/515#comments</comments>
		<pubDate>Sun, 15 Aug 2010 23:43:13 +0000</pubDate>
		<dc:creator>Josh McAdams</dc:creator>
				<category><![CDATA[administrative note]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=515</guid>
		<description><![CDATA[We have added support for OpenID to this site so that our commenters don&#8217;t have to manage yet another password. If you are creating a new account, you can create it with an OpenID from the start on the registration page. If you have an existing account and would like to link it to an [...]]]></description>
			<content:encoded><![CDATA[<p>We have added support for <a href="http://openid.net/">OpenID</a> to this site so that our commenters don&#8217;t have to manage yet another password. If you are creating a new account, you can create it with an OpenID from the start on the <a href="/wp-login.php?action=register">registration page</a>. If you have an existing account and would like to link it to an OpenID, just log in with your existing account credentials and click on the <a href="/wp-admin/users.php?page=your_openids">&#8220;Your OpenIDs&#8221; link</a> on the left of the user management page and do the linking there.</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=OpenID+Login+Now+Available+http://ypkky.th8.us" 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=OpenID+Login+Now+Available+http://ypkky.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/515&amp;title=OpenID+Login+Now+Available" 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/515&amp;title=OpenID+Login+Now+Available" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/515&amp;title=OpenID+Login+Now+Available" 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/515&amp;title=OpenID+Login+Now+Available" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/515&amp;t=OpenID+Login+Now+Available" 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/515&amp;t=OpenID+Login+Now+Available" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/515&amp;title=OpenID+Login+Now+Available" 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/515&amp;title=OpenID+Login+Now+Available" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/515/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Temporarily remove hash keys or array elements with `delete local`</title>
		<link>http://www.effectiveperlprogramming.com/blog/504</link>
		<comments>http://www.effectiveperlprogramming.com/blog/504#comments</comments>
		<pubDate>Sun, 15 Aug 2010 12:06:18 +0000</pubDate>
		<dc:creator>brian d foy</dc:creator>
				<category><![CDATA[5.12]]></category>
		<category><![CDATA[The Basics of Perl]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=504</guid>
		<description><![CDATA[Perl 5.12 adds a feature that lets you locally delete a hash key or array element (refresh your memory of local with Item 43: Know the difference between my and local. This new feature allows you to temporarily prune a hash or an array: delete local $hash{$key}; delete local $array[$index]; This syntax has actually been [...]]]></description>
			<content:encoded><![CDATA[<p>Perl 5.12 adds a feature that lets you locally <a href="http://perldoc.perl.org/functions/delete.html">delete</a> a hash key or array element (refresh your memory of <a href="http://perldoc.perl.org/functions/local.html">local</a> with <span class="item">Item 43: Know the difference between <code>my</code> and <code>local</code></span>. This new feature allows you to temporarily prune a hash or an array:</p>
<pre class="brush:perl">
delete local $hash{$key};
delete local $array[$index];
</pre>
<p>This syntax has actually been valid since at least Perl 5.6, although until Perl 5.12 it didn&#8217;t do anything different than a normal <a href="http://perldoc.perl.org/functions/delete.html">delete</a>. Using it doesn&#8217;t even issue a warning:</p>
<pre class="brush:plain">
$ perl5.6.2 -we 'delete local $ENV{PATH}'
</pre>
<p>This is documented in both in <a href="http://perldoc.perl.org/perlfunc.html">perlfunc</a> and, curiously, <a href="http://perldoc.perl.org/perlsub.html">perlsub</a></p>
<h2>Temporarily delete hash keys</h2>
<p>Setting up an inherited environment is one common reason that you would want to temporarily delete hash keys. You don&#8217;t want some values set when you run an external program: </p>
<pre class="brush:perl">
{
delete local $ENV{DISPLAY};
system( 'some_program', @args );
}
</pre>
<p>Before Perl 5.12, you could temporarily delete hash keys in two steps. The first step requires you to assign the current hash to a new local version so you start off with all the current values. In the second step, you can delete the keys that you don&#8217;t want:</p>
<pre class="brush:perl">
use Data::Dumper;

%ENV = qw(
	PATH     /usr/bin:/usr/local/bin
	PERL5LIB /Users/buster/lib/perl5
	DISPLAY  localhost:0
	);

print_env( 'Top level = ' );

{
local %ENV = %ENV;      # Step 1
delete $ENV{PATH};      # Step 2

print_env( 'Inner level = ' );
}

print_env( 'Back at top level = ' );

sub print_env {
	print @_, Dumper( \%ENV ), "\n";
	}
</pre>
<p>The output shows you that the <code>PATH</code> key temporarily disappears:</p>
<pre class="brush:plain">
Top level = $VAR1 = {
          'DISPLAY' => 'localhost:0',
          'PERL5LIB' => '/Users/buster/lib/perl5',
          'PATH' => '/usr/bin:/usr/local/bin'
        };

Inner level = $VAR1 = {
          'DISPLAY' => 'localhost:0',
          'PERL5LIB' => '/Users/buster/lib/perl5'
        };

Back at top level = $VAR1 = {
          'DISPLAY' => 'localhost:0',
          'PERL5LIB' => '/Users/buster/lib/perl5',
          'PATH' => '/usr/bin:/usr/local/bin'
        };
</pre>
<p>Deleting a hash key is different from localizing the key and setting an <code>undef</code> value (which is the same as not giving it a new value): </p>
<pre class="brush:perl">
{
local $ENV{PATH};

print_env( 'Inner level = ' );
}
</pre>
<p>This doesn&#8217;t remove the hash key, which might be important:</p>
<pre class="brush:plain">
Inner level = $VAR1 = {
          'DISPLAY' => 'localhost:0',
          'PERL5LIB' => '/Users/buster/lib/perl5',
          'PATH' => undef
        };
</pre>
<p>The presence of a key, even with an <code>undef</code> value, can mean something much different than the absence of a key. For instance, you might not get the default value your application might set when the hash key is missing.</p>
<h2>Do it in one step with Perl 5.12</h2>
<p>You can get the same thing with one step with Perl 5.12, and you get the same output as the first program:</p>
<pre class="brush:perl">
use 5.012;

use Data::Dumper;

%ENV = qw(
	PATH     /usr/bin:/usr/local/bin
	PERL5LIB /Users/buster/lib/perl5
	DISPLAY  localhost:0
	);

print_env( 'Top level = ' );

{
delete local $ENV{PATH};       # All together now

print_env( 'Inner level = ' );
}

print_env( 'Back at top level = ' );

sub print_env {
	say @_, Dumper( \%ENV );
	}
</pre>
<p>This even works for a hash slice so you can temporarily remove several keys. The syntax works out nicely because there&#8217;s nothing else to set:</p>
<pre class="brush:perl">
use 5.012;
delete local @ENV{qw( PATH DISPLAY )};
</pre>
<p>Curiously, this also works with lexical hashes, which you might not expect since the syntax uses <a href="">local</a>. Even though you use a lexical hash, it&#8217;s the <i>change to the hash</i> that&#8217;s local. That&#8217;s a bit weird. You can rearrange the <code>print_env</code> subroutine to be an anonymous subroutine defined at runtime so it can use the lexical variable:</p>
<pre class="brush:perl">
use 5.012;

use Data::Dumper;

my %env = qw(
	PATH     /usr/bin:/usr/local/bin
	PERL5LIB /Users/buster/lib/perl5
	DISPLAY  localhost:0
	);
my $print_env = sub { say @_, Dumper( \%env ); };

$print_env->( 'Top level = ' );

{
delete local @env{qw( PATH DISPLAY )};       # All together now

$print_env->( 'Inner level = ' );
}

$print_env->( 'Back in top level = ' );
</pre>
<h2>Temporarily undefined array values</h2>
<p>The <code>delete local</code> syntax also works with arrays, although it&#8217;s a bit different from the hash effect. When you delete an array element, you just set the value at that index to <code>undef</code>. That means that the array index is still there and the array does not change length (unless you&#8217;re deleting from the end):</p>
<pre class="brush:perl">
use 5.012;
use Data::Dumper;

my @array = qw(buster mimi roscoe ginger ellie);

my $print_array = sub { say @_, Dumper( \@array ); };

$print_array->( 'Top level = ' );

{
delete local $array[2];

$print_array->( 'Inner level = ' );
}

$print_array->( 'Back at top level = ' );
</pre>
<p>The output shows a hole in the array:</p>
<pre class="brush:plain">
Top level = $VAR1 = [
          'buster',
          'mimi',
          'roscoe',
          'ginger',
          'ellie'
        ];

Inner level = $VAR1 = [
          'buster',
          'mimi',
          undef,
          'ginger',
          'ellie'
        ];

Back at top level = $VAR1 = [
          'buster',
          'mimi',
          'roscoe',
          'ginger',
          'ellie'
        ];
</pre>
<p>If you temporarily want the array to not have an element, you&#8217;re in a bit of a pickle because you have to deal with package and lexical variables differently, although each requires you to make a copy.</p>
<h2>Things to remember</h2>
<p>If you have Perl 5.12 or later, you can:</p>
<ul>
<li>temporarily removes a hash key with <code>delete local $hash{$key}</code>.
<li>temporarily undefined an array element with <code>delete local $array[$index]</code>.
<li>apply <code>delete local</code> to lexical variables.
<li>use <code>delete local</code> with slices.
</ul>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Temporarily+remove+hash+keys+or+array+elements+with+%60delete+local%60+http://ewm9z.th8.us" 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=Temporarily+remove+hash+keys+or+array+elements+with+%60delete+local%60+http://ewm9z.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/504&amp;title=Temporarily+remove+hash+keys+or+array+elements+with+%60delete+local%60" 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/504&amp;title=Temporarily+remove+hash+keys+or+array+elements+with+%60delete+local%60" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/504&amp;title=Temporarily+remove+hash+keys+or+array+elements+with+%60delete+local%60" 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/504&amp;title=Temporarily+remove+hash+keys+or+array+elements+with+%60delete+local%60" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/504&amp;t=Temporarily+remove+hash+keys+or+array+elements+with+%60delete+local%60" 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/504&amp;t=Temporarily+remove+hash+keys+or+array+elements+with+%60delete+local%60" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/504&amp;title=Temporarily+remove+hash+keys+or+array+elements+with+%60delete+local%60" 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/504&amp;title=Temporarily+remove+hash+keys+or+array+elements+with+%60delete+local%60" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/504/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>We had to install CAPTCHA :(</title>
		<link>http://www.effectiveperlprogramming.com/blog/494</link>
		<comments>http://www.effectiveperlprogramming.com/blog/494#comments</comments>
		<pubDate>Sun, 08 Aug 2010 17:17:15 +0000</pubDate>
		<dc:creator>Josh McAdams</dc:creator>
				<category><![CDATA[administrative note]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=494</guid>
		<description><![CDATA[We&#8217;ve been getting quite a few automated user registrations here at &#8220;The Effective Perler&#8221;, some of which try to make spammy comments on old posts. In order to combat that, we&#8217;ve added a CAPTCHA that will show up when new users register. It shouldn&#8217;t show up for any existing users who are posting comments, so [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve been getting quite a few automated user registrations here at &#8220;The Effective Perler&#8221;, some of which try to make spammy comments on old posts. In order to combat that, we&#8217;ve added a CAPTCHA that will show up when new users register. It shouldn&#8217;t show up for any existing users who are posting comments, so hopefully it won&#8217;t be too annoying. Time will tell if this keeps the number of spam-users down.</p>
<p>In addition to adding the CAPTCHA, we deleted some of the user names that looked like fake users. If we accidentally deleted your real user account, we apologize. We made sure not to delete any accounts that had made legitimate comments.</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=We+had+to+install+CAPTCHA+%3A%28+http://opiy8.th8.us" 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=We+had+to+install+CAPTCHA+%3A%28+http://opiy8.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/494&amp;title=We+had+to+install+CAPTCHA+%3A%28" 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/494&amp;title=We+had+to+install+CAPTCHA+%3A%28" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/494&amp;title=We+had+to+install+CAPTCHA+%3A%28" 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/494&amp;title=We+had+to+install+CAPTCHA+%3A%28" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/494&amp;t=We+had+to+install+CAPTCHA+%3A%28" 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/494&amp;t=We+had+to+install+CAPTCHA+%3A%28" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/494&amp;title=We+had+to+install+CAPTCHA+%3A%28" 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/494&amp;title=We+had+to+install+CAPTCHA+%3A%28" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/494/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t make Perl do more work than it needs to</title>
		<link>http://www.effectiveperlprogramming.com/blog/474</link>
		<comments>http://www.effectiveperlprogramming.com/blog/474#comments</comments>
		<pubDate>Sun, 08 Aug 2010 03:20:46 +0000</pubDate>
		<dc:creator>Josh McAdams</dc:creator>
				<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=474</guid>
		<description><![CDATA[My choice of algorithms and data organization can lead to orders of magnitude of performance differences between functionally equivalent implementations of my programs. Choosing the right way to do something can save me orders of magnitude in processing. I wrote some code to loop over lines in a file and modify a couple of elements [...]]]></description>
			<content:encoded><![CDATA[<p>My choice of algorithms and data organization can lead to orders of magnitude of performance differences between functionally equivalent implementations of my programs. Choosing the right way to do something can save me orders of magnitude in processing.</p>
<p>I wrote some code to loop over lines in a file and modify a couple of elements in each line. My code seems very innocent, but the actual field modifications were a little more complex; I replaced them with <a href="http://perldoc.perl.org/functions/lc.html">lc</a> and <a href="http://perldoc.perl.org/functions/uc.html">uc</a> to make things simple for this example:</p>
<pre class="brush:perl">while (&lt;&gt;) {
  chomp;
  my @x = split "\t";
  $x[3] = lc $x[3];
  $x[5] = uc $x[5];
  print join("\t", @x), "\n";
}</pre>
<p>I have a loop that <a href="http://perldoc.perl.org/functions/split.html">split</a>s each line of a file on the tab character then modifies the fourth and sixth field.<br />
Look closely at the loop: I&#8217;m making Perl do a lot more work than it needs to. </p>
<p>First, I cal <a href="http://perldoc.perl.org/functions/chomp.html">chomp</a> on each line, but I&#8217;m adding the newline right back. There is no reason to do that. If I leave it there I get the same result:</p>
<pre class="brush:perl">while (&lt;&gt;) {
  my @x = split "\t";
  $x[3] = lc $x[3];
  $x[5] = uc $x[5];
  print join("\t", @x);
}</pre>
<p><a href="http://perldoc.perl.org/functions/chomp.html">chomp</a>ing when I don&#8217;t need to is a minor issue, but it is not likely going to destroy the performance of any program.</p>
<p>Looking a little closer, I see a much bigger inefficiency if I know the format of the data. Assume each line of data contains many fields; many being some number greater than six in this specific example. Since I&#8217;m are only acting on fields four and six, why do I <a href="http://perldoc.perl.org/functions/split.html">split</a> the entire line just to put it back together?</p>
<p>With a couple of more arguments, I can tell <a href="http://perldoc.perl.org/functions/split.html">split</a> to limit the number of fields it creates. I can limit my results to seven items since I don&#8217;t care to modify any beyond that:</p>
<pre class="brush:perl">while (&lt;&gt;) {
  my @x = split "\t", $_, 7;
  $x[3] = lc $x[3];
  $x[5] = uc $x[5];
  print join("\t", @x);
}</pre>
<p>If each line only contains seven, or even ten, elements, I won&#8217;t see much if any improvement. However, if each line contains dozens or hundreds of fields, my potential speed-up is huge.</p>
<p>There is even more I can do to milk performance out of my loop if I control the data format. If I move the columns that I need to modify to the front of each row, I don&#8217;t need to <a href="http://perldoc.perl.org/functions/split.html">split</a> into so many fields:</p>
<pre class="brush:perl">while (&lt;&gt;) {
  my @x = split "\t", $_, 3;
  $x[0] = lc $x[0];
  $x[1] = uc $x[1];
  print join("\t", @x);
}</pre>
<h2>Measure the improvement</h2>
<p>Just to be sure that these changes are really making my code faster, I do a little benchmarking to get a feel for the relative performance differences:</p>
<pre class="brush:perl">use warnings;
use strict;
use Benchmark qw(timethese);

my @data;

for (0..10_000) {
  $data[$_] = join "\t", map { chr(65 + (int rand(52))) } (0..100);
}

timethese(500, {
  'standard' =&gt; sub {
    for (@data) {
      chomp;
      my @x = split "\t";
      $x[3] = lc $x[3];
      $x[5] = uc $x[5];
      $_ = join("\t", @x) . "\n";
    }
  },
  'no_chomp' =&gt; sub {
    for (@data) {
      my @x = split "\t";
      $x[3] = lc $x[3];
      $x[5] = uc $x[5];
      $_ = join("\t", @x);
    }
  },
  'smaller' =&gt; sub {
    for (@data) {
      my @x = split "\t", $_, 7;
      $x[3] = lc $x[3];
      $x[5] = uc $x[5];
      $_ = join("\t", @x);
    }
  },
  'smallest' =&gt; sub {
    for (@data) {
      my @x = split "\t", $_, 3;
      $x[0] = lc $x[0];
      $x[1] = uc $x[1];
      $_ = join("\t", @x);
    }
  },
});</pre>
<p>In this benchmark I experimented on ten thousand records, each with a hundred fields. The benchmarks measure:</p>
<ul>
<li>the initial, or &#8220;standard&#8221; case.
<li>the case where I just removed a <a href="http://perldoc.perl.org/functions/chomp.html">chomp</a>, &#8220;no_chomp&#8221;.
<li>the case where I limit <a href="http://perldoc.perl.org/functions/split.html">split</a>, &#8220;smaller&#8221;.
<li>the case where I reorder the inbound data, &#8220;smallest&#8221;.
</ul>
<p>The [reordered] results tell me quite a bit:</p>
<blockquote><p>
Benchmark: timing 500 iterations of no_chomp, smaller, smallest, standard&#8230;<br />
standard: 451 wallclock secs (449.66 usr +  0.34 sys = 450.00 CPU) @  1.11/s (n=500)<br />
no_chomp: 451 wallclock secs (446.18 usr +  0.41 sys = 446.59 CPU) @  1.12/s (n=500)<br />
smaller: 39 wallclock secs (39.15 usr +  0.03 sys = 39.18 CPU) @ 12.76/s (n=500)<br />
smallest: 19 wallclock secs (18.98 usr +  0.01 sys = 18.99 CPU) @ 26.33/s (n=500)
</p></blockquote>
<p>Removing <a href="http://perldoc.perl.org/functions/chomp.html">chomp</a> had an almost unnoticeable effect. However, I recuded my processing tenfold by limiting <a href="http://perldoc.perl.org/functions/split.html">split</a>. I made my code even faster by reordering the inbound data.</p>
<p>Just to see what effect number of fields really has, I reduced the size of the data so that each record had ten fields. The results were obviously less impressive, though still visible:</p>
<blockquote><p>
Benchmark: timing 500 iterations of no_chomp, smaller, smallest, standard&#8230;<br />
  standard: 58 wallclock secs (57.50 usr +  0.05 sys = 57.55 CPU) @  8.69/s (n=500)<br />
  no_chomp: 55 wallclock secs (55.13 usr +  0.04 sys = 55.17 CPU) @  9.06/s (n=500)<br />
   smaller: 38 wallclock secs (37.67 usr +  0.03 sys = 37.70 CPU) @ 13.26/s (n=500)<br />
  smallest: 18 wallclock secs (18.46 usr +  0.01 sys = 18.47 CPU) @ 27.07/s (n=500)
</p></blockquote>
<p>So what does this tell me? Well, as far as a specific optimization goes, limiting <a href="http://perldoc.perl.org/functions/split.html">split</a> is probably a good idea if I&#8217;m trying to optimize my processing and really don&#8217;t need every field.</p>
<p>However, there is a larger moral to this story and that is: When performance is a concern, don&#8217;t make your code do work that it doesn&#8217;t have too. The most important is my choice of algorithms and related data structures for solving my problem. This can make or break my performance. After that, knowing specific optimizations such as limiting  <a href="http://perldoc.perl.org/functions/split.html">split</a> fields, help me get just a little more performance out of my code.</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Don%E2%80%99t+make+Perl+do+more+work+than+it+needs+to+http://x3pcc.th8.us" 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=Don%E2%80%99t+make+Perl+do+more+work+than+it+needs+to+http://x3pcc.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/474&amp;title=Don%E2%80%99t+make+Perl+do+more+work+than+it+needs+to" 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/474&amp;title=Don%E2%80%99t+make+Perl+do+more+work+than+it+needs+to" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/474&amp;title=Don%E2%80%99t+make+Perl+do+more+work+than+it+needs+to" 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/474&amp;title=Don%E2%80%99t+make+Perl+do+more+work+than+it+needs+to" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/474&amp;t=Don%E2%80%99t+make+Perl+do+more+work+than+it+needs+to" 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/474&amp;t=Don%E2%80%99t+make+Perl+do+more+work+than+it+needs+to" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/474&amp;title=Don%E2%80%99t+make+Perl+do+more+work+than+it+needs+to" 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/474&amp;title=Don%E2%80%99t+make+Perl+do+more+work+than+it+needs+to" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/474/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Do you want extra Effective Perl in Safari Books?</title>
		<link>http://www.effectiveperlprogramming.com/blog/485</link>
		<comments>http://www.effectiveperlprogramming.com/blog/485#comments</comments>
		<pubDate>Fri, 06 Aug 2010 01:33:34 +0000</pubDate>
		<dc:creator>brian d foy</dc:creator>
				<category><![CDATA[eBook]]></category>
		<category><![CDATA[reader feedback]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=485</guid>
		<description><![CDATA[We&#8217;re looking for some reader feedback. You can comment here, send us mail, reply on Twitter, skywrite your message in Chicago (please send us a link to that video in case we miss it), or come up to us at a conference. We&#8217;re thinking about writing an extra, bonus chapter of Effective Perl Programming for [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;re looking for some reader feedback. You can comment here, send us mail, reply on Twitter, skywrite your message in Chicago (please send us a link to that video in case we miss it), or come up to us at a conference.</p>
<p>We&#8217;re thinking about writing an extra, bonus chapter of <a href="http://my.safaribooksonline.com/9780321718303"><i>Effective Perl Programming</i> for Safari Books Online</a>. We&#8217;re having fun providing lots of free, extra content on this website, but we thought we might do something nice for those you also paid to get online access to our book.</p>
<p>Before we commit to too much, we&#8217;d like to find out a little bit about our readers to make sure it&#8217;s worth it:</p>
<ul>
<li>How many of you are reading <i>Effective Perl Programming</i> through Safari?
<li>Does your company provide you with an unlimited Safari account?
<li>If we added bonus material, would you be more likely to buy our book in Safari?
<li>If you don&#8217;t want to use Safari, would you be more likely to buy another e-book format with extra content?
<li>If you aren&#8217;t reading our book in a digital form, why not? Is there anything that would change your mind?
</ul>
<p>We&#8217;re still going to pump out more Effective Perler tips and techniques for free (It&#8217;s already August and we&#8217;ve done at least one significant post per week this year!).</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Do+you+want+extra+Effective+Perl+in+Safari+Books%3F+http://nqxpd.th8.us" 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=Do+you+want+extra+Effective+Perl+in+Safari+Books%3F+http://nqxpd.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/485&amp;title=Do+you+want+extra+Effective+Perl+in+Safari+Books%3F" 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/485&amp;title=Do+you+want+extra+Effective+Perl+in+Safari+Books%3F" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/485&amp;title=Do+you+want+extra+Effective+Perl+in+Safari+Books%3F" 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/485&amp;title=Do+you+want+extra+Effective+Perl+in+Safari+Books%3F" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/485&amp;t=Do+you+want+extra+Effective+Perl+in+Safari+Books%3F" 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/485&amp;t=Do+you+want+extra+Effective+Perl+in+Safari+Books%3F" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/485&amp;title=Do+you+want+extra+Effective+Perl+in+Safari+Books%3F" 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/485&amp;title=Do+you+want+extra+Effective+Perl+in+Safari+Books%3F" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/485/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Implicitly turn on strictures with Perl 5.12</title>
		<link>http://www.effectiveperlprogramming.com/blog/468</link>
		<comments>http://www.effectiveperlprogramming.com/blog/468#comments</comments>
		<pubDate>Sun, 01 Aug 2010 15:09:46 +0000</pubDate>
		<dc:creator>brian d foy</dc:creator>
				<category><![CDATA[5.12]]></category>
		<category><![CDATA[Programming tips]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=468</guid>
		<description><![CDATA[Perl 5.12 can turn on strict for you automatically, stealing a feature from Modern::Perl that takes away one line of boilerplate in your Perl programs and modules. We talk about strict in Item 3: Enable strictures to promote better coding. Similar to what we show in Item 2: Enable new Perl features when you need [...]]]></description>
			<content:encoded><![CDATA[<p>Perl 5.12 can turn on strict for you automatically, stealing a feature from <a href="http://search.cpan.org/dist/Modern-Perl">Modern::Perl</a> that takes away one line of boilerplate in your Perl programs and modules. We talk about <a href="http://perldoc.perl.org/strict.html">strict</a> in <span class="item">Item 3: Enable strictures to promote better coding</span>. Similar to what we show in <span class="item">Item 2: Enable new Perl features when you need them</span>, to turn strictures on automatically, you have to use <a href="http://perldoc.perl.org/functions/use.html">use</a> with a version of Perl 5.11.0 or later:</p>
<pre class="brush:perl">
use 5.012;
</pre>
<p>This is really just the same thing as explicitly turning on <a href="http://perldoc.perl.org/strict.html">strict</a> and importing the <code>5.12</code> feature bundle:</p>
<pre class="brush:perl">
use strict;
use feature ':5.12';
</pre>
<p>Note that this means merely importing the feature bundle <i>does not</i> include this implicit strictures benefit. Don&#8217;t think you&#8217;re safe merely because you are using a <code>perl5.12</code> interpreter.</p>
<p>Similarly, using the <code>-E</code> switch, which imports the feature bundle for that version of Perl, does not turn on strictures. You can import strict explicitly (although you are probably not interested in strictures on the command line):</p>
<pre class="brush:perl">
% perl5.12.1 -E '$sum = 0;'
% perl5.12.1 -Mstrict -E '$sum = 0;'
Global symbol "$sum" requires explicit package name at -e line 1.
Execution of -e aborted due to compilation errors.
</pre>
<p>Remember, however, that <code>strict</code> is lexically scoped, and that a file is a scope (<a href="http://www.effectiveperlprogramming.com/blog/48">Know what creates a scope</a>). That is, the <code>use 5.012</code> only affects the file that it is in, but any files it loads do not have to be <code>strict</code>-clean.</p>
<p>Consider this <code>strict</code>-dirty module:</p>
<pre class="brush:perl">
# NoStrict.pm
package NoStrict;

$sum = 0;

1;
</pre>
<p>When you load it in a program, any <code>strict</code> settings do not descend into <i>NoStrict.pm</i>:</p>
<pre class="brush:perl">
use 5.012;

use lib qw(.);
use NoStrict; # strict dirty module

my $sum = 0;
</pre>
<p>When you run this program, it compiles just fine:</p>
<pre class="brush:plain">
perl5.12.1 strict.pl
</pre>
<p>To get around this, you have to set <code>strict</code> in every file you want to apply it to.</p>
<h2>Things to remember</h2>
<ul>
<li><code>use 5.012</code> turns on strictures in it&#8217;s file
<li>The implicit strictures feature is not part of the <code>5.12</code> feature bundle
<li>The <code>-E</code> command-line switch does not turn on strictures.
</ul>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Implicitly+turn+on+strictures+with+Perl+5.12+http://wgmek.th8.us" 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=Implicitly+turn+on+strictures+with+Perl+5.12+http://wgmek.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/468&amp;title=Implicitly+turn+on+strictures+with+Perl+5.12" 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/468&amp;title=Implicitly+turn+on+strictures+with+Perl+5.12" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/468&amp;title=Implicitly+turn+on+strictures+with+Perl+5.12" 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/468&amp;title=Implicitly+turn+on+strictures+with+Perl+5.12" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/468&amp;t=Implicitly+turn+on+strictures+with+Perl+5.12" 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/468&amp;t=Implicitly+turn+on+strictures+with+Perl+5.12" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/468&amp;title=Implicitly+turn+on+strictures+with+Perl+5.12" 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/468&amp;title=Implicitly+turn+on+strictures+with+Perl+5.12" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/468/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Turn off Perl 5.12 deprecation warnings, if you dare!</title>
		<link>http://www.effectiveperlprogramming.com/blog/463</link>
		<comments>http://www.effectiveperlprogramming.com/blog/463#comments</comments>
		<pubDate>Sun, 25 Jul 2010 13:15:23 +0000</pubDate>
		<dc:creator>brian d foy</dc:creator>
				<category><![CDATA[5.12]]></category>
		<category><![CDATA[miscellany]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=463</guid>
		<description><![CDATA[Perl 5.12 deprecates several features, for various reasons. Some of the features were always stupid, some need to make way for future development, and some are just too ornery to maintain. All of these are listed in the perldelta5120 documentation. The new thing, however, is that Perl 5.12 will warn you about these even if [...]]]></description>
			<content:encoded><![CDATA[<p>Perl 5.12 deprecates several features, for various reasons. Some of the features were always stupid, some need to make way for future development, and some are just too ornery to maintain. All of these are listed in the <a href="http://perldoc.perl.org/perl5120delta.html">perldelta5120</a> documentation. The new thing, however, is that Perl 5.12 will warn you about these even if you don&#8217;t have warnings turned on. Consider this script full of Perl whoppers:</p>
<pre class="brush:perl">
use 5.012;

use Switch;             # use given-when
use UNIVERSAL qw(can);  # no more UNIVERSAL->import

$[ = 1;       # I like FORTRAN.
my $pi := 4;  # empty attribute, not a special assignment

OUTER: {
	goto INNER;  # can't jump into inner scope
	...;
	MIDDLE: {
		...;
		INNER: {
			hello();
			}
		}
	}

sub hello :locked { # no more locked attribute
	say 'Here I am!';
	}
</pre>
<p>When you run this program, you get some warnings:</p>
<pre class="brush:plain">
% perl5.12.1 old_stuff.pl
Use of assignment to $[ is deprecated at old_stuff.pl line 6.
Use of := for an empty attribute list is deprecated at old_stuff.pl line 7.
Use of :locked is deprecated at old_stuff.pl line 20.
Use of "goto" to jump into a construct is deprecated at old_stuff.pl line 9.
Here I am!
</pre>
<p>If you enable warnings, you get even more deprecation warnings:</p>
<pre class="brush:plain">
% perl5.12.1 -w old_stuff.pl
Switch will be removed from the Perl core distribution in the next major release. Please install it from CPAN. It is being used at old_stuff.pl, line 3.
UNIVERSAL->import is deprecated and will be removed in a future perl at old_stuff.pl line 4
Use of assignment to $[ is deprecated at old_stuff.pl line 6.
Use of := for an empty attribute list is deprecated at old_stuff.pl line 7.
Use of :locked is deprecated at old_stuff.pl line 20.
Use of "goto" to jump into a construct is deprecated at old_stuff.pl line 9.
Here I am!
</pre>
<p>If you still want to use these features, despite Perl doing everything it can to warn you not to, you can explicitly turn off the <code>deprecation</code> warning class:</p>
<pre class="brush:perl">
use 5.012;
no warnings 'deprecated';

# same as before...
</pre>
<p>Now you just get the output that you wanted:</p>
<pre class="brush:plain">
$ perl5.12.1 -w old_stuff.pl
Here I am!
</pre>
<p>You shouldn&#8217;t turn off these warnings as a long term strategy. If you&#8217;re migrating your ancient Perl to the latest version and want these warnings to temporarily disappear while you focus on some other things, we can let that pass. You might want to give yourself a reminder that you&#8217;ve turned off all of these important warnings by checking for warnings as we showed in <span class="item">Item 100: Use lexical warnings to selectively turn on or turn off complaints</span. You replace possibly a long list of warnings with a single one:</p>
<pre class="brush:perl">
use 5.012;
no warnings &#8216;deprecated&#8217;;
temp_warning();

sub temp_warning {
	# needs to be one level lower than the warnings setting
	warn &#8220;Hey Evel Knievel! Deprecation warnings are disabled!&#8221; unless
		warnings::enabled( &#8216;deprecated&#8217; );
	}

&#8230;;
</pre>
<p>It's important that you put your check inside a subroutine because <code>warnings::enabled</code> is specifically designed to look on level above where you call it since it's expecting you to use it in a module to respect the state of the calling script.</p>
<p>Since the warnings pragma is lexically scoped, you might have to do this in several places (unless the modules respect the warnings settings of the caller!). Don't expect anyone to rush to make it any easier for you to disengage the safety devices, though!</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Turn+off+Perl+5.12+deprecation+warnings%2C+if+you+dare%21+http://gna6d.th8.us" 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=Turn+off+Perl+5.12+deprecation+warnings%2C+if+you+dare%21+http://gna6d.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/463&amp;title=Turn+off+Perl+5.12+deprecation+warnings%2C+if+you+dare%21" 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/463&amp;title=Turn+off+Perl+5.12+deprecation+warnings%2C+if+you+dare%21" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/463&amp;title=Turn+off+Perl+5.12+deprecation+warnings%2C+if+you+dare%21" 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/463&amp;title=Turn+off+Perl+5.12+deprecation+warnings%2C+if+you+dare%21" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/463&amp;t=Turn+off+Perl+5.12+deprecation+warnings%2C+if+you+dare%21" 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/463&amp;t=Turn+off+Perl+5.12+deprecation+warnings%2C+if+you+dare%21" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/463&amp;title=Turn+off+Perl+5.12+deprecation+warnings%2C+if+you+dare%21" 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/463&amp;title=Turn+off+Perl+5.12+deprecation+warnings%2C+if+you+dare%21" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/463/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Locate bugs with source control bisection</title>
		<link>http://www.effectiveperlprogramming.com/blog/451</link>
		<comments>http://www.effectiveperlprogramming.com/blog/451#comments</comments>
		<pubDate>Mon, 19 Jul 2010 10:02:13 +0000</pubDate>
		<dc:creator>brian d foy</dc:creator>
				<category><![CDATA[debugging]]></category>
		<category><![CDATA[git]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=451</guid>
		<description><![CDATA[As you work in Perl you store each step in source control. When you finish a little bit of work, you commit your work. Ideally, every commit deals with one thing so you&#8217;re only introducing one logical change in each revision. Somewhere along the process, you might discover that something is not working correctly. You [...]]]></description>
			<content:encoded><![CDATA[<p>As you work in Perl you store each step in source control. When you finish a little bit of work, you commit your work. Ideally, every commit deals with one thing so you&#8217;re only introducing one logical change in each revision.</p>
<p>Somewhere along the process, you might discover that something is not working correctly. You think that it used to work but you&#8217;re not sure where things went pear-shaped, perhaps because the bug seemingly deals with something that you weren&#8217;t working on.</p>
<p>You might think that your test suite should catch those, but a test suite doesn&#8217;t protect you from bugs. Your tests might not have checked for the problem, or your tests might have been wrong, or all sorts of other things that you don&#8217;t expect. Your tests are only as good as you make them, and often the programmer creates his own tests and acts as his own quality control (which isn&#8217;t the best of arrangements).</p>
<p>Since you&#8217;re keeping your work in source control (we&#8217;ll give you the benefit of the doubt), you can easily, at least in process, figure out where the problem appears by <i>bisecting</i> your source tree until you find the revision that introduces the problem:</p>
<ol>
<li>check out a revision where things don&#8217;t work</li>
<li>verify broken behavior with a test script</li>
<li>check out a revision where you think things work</li>
<li>verify working behavior with a test script</li>
<li>check out a revision halfway between the working and broken versions</li>
<li>run the test script to check if that revision works or breaks</li>
<li>repeat this bisection until you find revision that breaks</li>
</ol>
<p>With each iteration, you narrow the window of revisions where you might have introduced the problem.</p>
<p>This is simple in process, but it&#8217;s tedious in practice. With any source control system, you can manually checkout a revision, run your check script, and see what happens. You can keep doing that until you find the problem. You can even automate it.</p>
<p>Some modern source control systems, however, provide a bisection feature for you so you don&#8217;t have to automate it yourself. For this Item, consider <code>git</code>, which is popular in the Perl community (and the <code>perl</code> source is in a git repository). Read <a href="http://www.nntp.perl.org/group/perl.perl5.porters/">perl5-porters</a> for a couple of days and you&#8217;re likely to read about some of the developers using <code>git bisect</code> to find a bug in <code>perl</code>.</p>
<p>As a demonstration, you can use the <a href="http://www.effectiveperlprogramming.com/wp-content/uploads/Buster-Bean-bisect.tgz"><code>Buster::Bean</code> git repository</a>. In that module which simulates my cat, there&#8217;s a <code>complaino</code> subroutine that should return a string that has &#8220;meow&#8221; in it, but somewhere along the line it broke. The <i>t/export.t</i> test checks for this, and you notice in the latest revision that the <i>t/export.t</i> test doesn&#8217;t pass.</p>
<pre class="brush:perl">
# t/export.t
like( complaino(), qr/meow/i, 'complaino returns something like a meow' );
</pre>
<p>The current version of <code>complaino</code> is broken, but you don&#8217;t remember when it broke:</p>
<pre class="brush:perl">
# lib/Bean.pm
sub complaino {
	return 'MEOOOOOW!' # this versions is broken
	}
</pre>
<p>Once you unpack the distribution, change into the <i>Buster-Bean</i> directory if you want to follow along.</p>
<p>To start your hunt, you tell <code>git</code> that you are starting a bisection:</p>
<pre class="brush:plain">
% git bisect start
</pre>
<p>Next you have to set the initial window. As with many things in <code>git</code>, you can specify the revision in various way. In this case, you can use the start of the SHA-1 digest for each commit. You set the <code>good</code> and <code>bad</code> bounds of the window:</p>
<pre class="brush:plain">
% git bisect good 4be027af
% git bisect bad 14883968
</pre>
<p>Once you&#8217;ve set the window for your bisection, you run the bisection by specifying a test script to run for each commit that <code>git</code> will check:</p>
<pre class="brush:plain">
% git bisect run ./test-script.sh
</pre>
<p>The trick is to write a test script that tells <code>git</code> if the revision works or not. If your test script exits with 0, you&#8217;re telling <code>git</code> that the revision works. If your test script exits with 1-127, that commit fails (although exiting with 125 tells <code>git</code> to skip that revision).</p>
<p>How you write your test script depends on what you want to check. In the case of <code>complaino</code>, you want to find where the <i>t/export.t</i> test starts to fail. You might think that you can just run the your test script:</p>
<pre class="brush:plain">
% git bisect run perl -Iblib/lib t/export.t
</pre>
<p>However, that might not put the right versions of the modules in <i>blib</i>. In this case, you need to run <i>Makefile.PL</i> each time then <code>make</code> the source (or <code>./Build</code> it to put everything in the righ place. With the right files, you run the program that provides the final exit code to tell <code>git</code> what happened:</p>
<pre class="brush:plain">
#!/bin/sh

perl Makefile.PL
make
perl -Iblib/lib t/export.t
</pre>
<p>Now you&#8217;re to run the bisection:</p>
<pre class="brush:plain">
% git bisect run ./meow_test.sh
</pre>
<p>The output shows <code>git</code>&#8216;s progress through the revision history. The first revision it tests is in the middle of the the window you specified. In this case, that one passes, so it&#8217;s now the good bound of the window. The next revision is <code>93d1747</code>, where <i>t/export.t</i> fails. That narrows the window on the bad side. The rest of the bisection tries revisions that all pass, so <code>93d1747</code> must be the revision that introduces that brokenness. <code>git</code> reports <code>93d1747... is first bad commit</code>:</p>
<pre class="brush:plain">
running ./meow_test.sh
Writing Makefile for Buster::Bean
Skip blib/lib/Buster/Bean.pm (unchanged)
Manifying blib/man3/Buster::Bean.3
1..4
ok 1 - use Buster::Bean;
ok 2 - Buster::Bean->can('complaino')
ok 3 - complaino subroutine is defined
ok 4 - complaino returns something like a meow

Bisecting: 3 revisions left to test after this
[93d1747e4681ea21536a66aba25bb21e1cddda05] Make uppercase
running ./meow_test.sh
Writing Makefile for Buster::Bean
cp lib/Bean.pm blib/lib/Buster/Bean.pm
Manifying blib/man3/Buster::Bean.3
1..4
ok 1 - use Buster::Bean;
ok 2 - Buster::Bean->can('complaino')
ok 3 - complaino subroutine is defined
not ok 4 - complaino returns something like a meow
#   Failed test 'complaino returns something like a meow'
#   at t/export.t line 10.
#                   'MEOOOOOW!'
#     doesn't match '(?i-xsm:meow)'
# Looks like you failed 1 test of 4.

Bisecting: 1 revisions left to test after this
[980be46fa2ea3ee32372aedd62949a663c729058] * Use fewer exclamation points
running ./meow_test.sh
Writing Makefile for Buster::Bean
cp lib/Bean.pm blib/lib/Buster/Bean.pm
Manifying blib/man3/Buster::Bean.3
1..4
ok 1 - use Buster::Bean;
ok 2 - Buster::Bean->can('complaino')
ok 3 - complaino subroutine is defined
ok 4 - complaino returns something like a meow

Bisecting: 0 revisions left to test after this
[b5ab15611ca25c6925998463c9cb7b079fe87c8b] * Make it lowercase
running ./meow_test.sh
Writing Makefile for Buster::Bean
cp lib/Bean.pm blib/lib/Buster/Bean.pm
Manifying blib/man3/Buster::Bean.3
1..4
ok 1 - use Buster::Bean;
ok 2 - Buster::Bean->can('complaino')
ok 3 - complaino subroutine is defined
ok 4 - complaino returns something like a meow

93d1747e4681ea21536a66aba25bb21e1cddda05 is first bad commit
commit 93d1747e4681ea21536a66aba25bb21e1cddda05
Author: brian d foy <brian.d.foy@gmail.com>
Date:   Mon Jul 19 20:43:07 2010 -0500

    Make uppercase

:040000 040000 8360932159317f0685b98f2b2dba4753c53e6240 0e7a2e5d54de7db9f1b790ed4da0a704612ba130 M  lib
bisect run success
</pre>
<p>Graphically, that bisection looks like this, starting at the top and going toward the bottom for &#9312; then on its way back toward the top for &#9313;, alternating directions as it closes in on the bad revision:</p>
<div align="center">
<img src="http://www.effectiveperlprogramming.com/wp-content/uploads/bisect.png" width="266" height="608" />
</div>
<p>When you are done with the your bisection, you need to tell <code>git</code> to return to the head of the source tree:</p>
<pre class="brush:plain">
% git bisect reset
</pre>
<p>Other source control systems have a bisection feature which do basically the same thing although their details might be different. If your source control system doesn&#8217;t have this feature, you can automate it (or switch to a system that does have it). Once set-up, you should be be able to locate bugs much quicker.</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Locate+bugs+with+source+control+bisection+http://engcm.th8.us" 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=Locate+bugs+with+source+control+bisection+http://engcm.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/451&amp;title=Locate+bugs+with+source+control+bisection" 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/451&amp;title=Locate+bugs+with+source+control+bisection" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/451&amp;title=Locate+bugs+with+source+control+bisection" 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/451&amp;title=Locate+bugs+with+source+control+bisection" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/451&amp;t=Locate+bugs+with+source+control+bisection" 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/451&amp;t=Locate+bugs+with+source+control+bisection" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/451&amp;title=Locate+bugs+with+source+control+bisection" 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/451&amp;title=Locate+bugs+with+source+control+bisection" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/451/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Perl Authors Night at Powell&#8217;s Technical Books</title>
		<link>http://www.effectiveperlprogramming.com/blog/427</link>
		<comments>http://www.effectiveperlprogramming.com/blog/427#comments</comments>
		<pubDate>Wed, 14 Jul 2010 00:18:29 +0000</pubDate>
		<dc:creator>brian d foy</dc:creator>
				<category><![CDATA[book signing]]></category>
		<category><![CDATA[event announcement]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=427</guid>
		<description><![CDATA[During OSCON, Joshua and I are taking part in the Perl Authors Night at Powell&#8217;s Technical Books on Tuesday, July 20 at 7 pm. Bring your copy of Effective Perl Programming for us to sign. Other authors confirmed so far include: chromatic (Modern Perl, Perl Testing: A Developer&#8217;s Notebook, Perl Hacks, Extreme Programming Pocket Guide) [...]]]></description>
			<content:encoded><![CDATA[<p>During OSCON, Joshua and I are taking part in the Perl Authors Night at <a href="http://www.powells.com/technicalbooks">Powell&#8217;s Technical Books</a> on Tuesday, July 20 at 7 pm. Bring your copy of <i>Effective Perl Programming</i> for us to sign.</p>
<p>Other authors confirmed so far include:</p>
<ul>
<li>
<b>chromatic</b> (<i>Modern Perl</i>, <i>Perl Testing: A Developer&#8217;s Notebook</i>, <i>Perl Hacks</i>, <i>Extreme Programming Pocket Guide</i>)</p>
<li>
<b>brian d foy</b> (<i>Effective Perl Programming</i>, <i>Learning Perl</i>, <i>Intermediate Perl</i>, <i>Mastering Perl</i>) </p>
<li>
<b>Joshua McAdams</b> (<i>Effective Perl Programming</i>)</p>
<li>
<b>Curtis &#8220;Ovid&#8221; Poe</b> (<i>Perl Hacks</i>)</p>
<li>
<b>Randal Schwartz</b> (<i>Programming perl (1st edition)</i>, <i>Learning Perl</i>, <i>Intermediate Perl</i>, <i>Perls of Wisdom</i>)</p>
<li>
<b>Peter Scott</b> (<i>Perl Medic</i>, <i>Perl Debugged</i>, <i>Perl Fundamentals (DVD)</i>)</p>
</ul>
<p>Make sure that you&#8217;re going to Powell&#8217;s Technical Books is at 33 Northwest Park Avenue in Portland, and not one of their other Portland stores. You can take the MAX Green line (for free) from the Convention Center to NW 5th St and NW Couch St, then walk 4 blocks west to the store.</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Perl+Authors+Night+at+Powell%E2%80%99s+Technical+Books+http://8ifk6.th8.us" 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=Perl+Authors+Night+at+Powell%E2%80%99s+Technical+Books+http://8ifk6.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/427&amp;title=Perl+Authors+Night+at+Powell%E2%80%99s+Technical+Books" 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/427&amp;title=Perl+Authors+Night+at+Powell%E2%80%99s+Technical+Books" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/427&amp;title=Perl+Authors+Night+at+Powell%E2%80%99s+Technical+Books" 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/427&amp;title=Perl+Authors+Night+at+Powell%E2%80%99s+Technical+Books" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/427&amp;t=Perl+Authors+Night+at+Powell%E2%80%99s+Technical+Books" 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/427&amp;t=Perl+Authors+Night+at+Powell%E2%80%99s+Technical+Books" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/427&amp;title=Perl+Authors+Night+at+Powell%E2%80%99s+Technical+Books" 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/427&amp;title=Perl+Authors+Night+at+Powell%E2%80%99s+Technical+Books" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/427/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Keep your programmatic configuration DRY</title>
		<link>http://www.effectiveperlprogramming.com/blog/407</link>
		<comments>http://www.effectiveperlprogramming.com/blog/407#comments</comments>
		<pubDate>Mon, 12 Jul 2010 12:00:50 +0000</pubDate>
		<dc:creator>Josh McAdams</dc:creator>
				<category><![CDATA[Programming tips]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=407</guid>
		<description><![CDATA[A common mantra among programmers today is to keep your code DRY. This little acronym stands for "Don't Repeat Yourself" and serves as a reminder that when you see a repetitive pattern in your code or are tempted to copy/paste some statements, you should think twice and consider extracting the common logic into a chunk of code that can be reused.

For many programmers, this practice begins to break down when "configuration" code is involved. When I talk about configuration code here, I'm not talking about the XML, YAML, INI, etc. bits of your project. I'm talking about the Perl code in your program that simply serves as data to feed some active portion of your code.]]></description>
			<content:encoded><![CDATA[<p>A common mantra among programmers today is to keep your code DRY. This little acronym stands for &#8220;Don&#8217;t Repeat Yourself&#8221; and serves as a reminder that when you see a repetitive pattern in your code or are tempted to copy/paste some statements, you should think twice and consider extracting the common logic into a chunk of code that can be reused.</p>
<p>For many programmers, this practice begins to break down when &#8220;configuration&#8221; code is involved. When I talk about configuration code here, I&#8217;m not talking about the XML, YAML, INI, and other non-moving bits of your project. I&#8217;m talking about the Perl code in your program that simply serves as data to feed some active portion of your code. For example:</p>
<pre class="brush:perl">my @anchors = (
  {
    text =&gt; 'Effective Perl',
    href =&gt; 'http://www.effectiveperlprogramming.com'
  },
  {
    text =&gt; 'Perl',
    href =&gt; 'http://www.perl.org'
  },
);

for my $anchor (@anchors) {
  create_anchor_tag($anchor);
}</pre>
<p>Here I have avoided repeating myself by consolidating all of the common logic for anchor processing into <code>create_anchor_tag</code>. My code loops the configuration data structure and simply feeds a little bit of configuration at a time into that subroutine.</p>
<p>This type of configuration works most of the time, especially when code is first written. Unfortunately, it breaks down quickly as the configuration becomes more complex over time. Say for instance that we now have more anchors and need to be more specific about the details of each anchor.</p>
<pre class="brush:perl">my @anchors = (
  {
    text  =&gt; 'Effective Perl',
    href  =&gt; 'http://www.effectiveperlprogramming.com',
    class =&gt; 'standard',
    style =&gt; '',
    lang  =&gt; 'en',
    dir   =&gt; 'ltr'
  },
  {
    text  =&gt; 'Perl',
    href  =&gt; 'http://www.perl.org',
    class =&gt; 'standard',
    style =&gt; '',
    lang  =&gt; 'en',
    dir   =&gt; 'ltr'
  },
  {
    text  =&gt; 'Perl Foundation',
    href  =&gt; 'http://www.perlfoundation.org',
    class =&gt; 'standard',
    style =&gt; '',
    lang  =&gt; 'en',
    dir   =&gt; 'ltr'
  },
  {
    text  =&gt; 'Perl6 России',
    href  =&gt; 'http://www.perl6.ru',
    class =&gt; 'standard',
    style =&gt; '',
    lang  =&gt; 'ru',
    dir   =&gt; 'ltr'
  },
  # ... and so on
);</pre>
<p>You can see, that beyond simply repeating the hash keys over and over, I am also repeating quite a few of the hash values. For instance, the values for <code>class</code>, <code>lang</code>, and <code>dir</code> are fairly consistant. When you see this pattern occurring in your code, it is time to do a little refactoring. Luckily, refactoring repetitiveness out of code is often very easy.</p>
<p>A common strategy for refactoring is to simply inline a <code><a title="Perl map function" href="http://perldoc.perl.org/functions/map.html">map</a></code> statement into the configuration setup. In the example below, I have inserted a <code>map</code> that handes the portions of the configuration that change the least. It provides default values that represent the most commonly used configuration values and also allows for overrides by overlaying the anchor-specific hash at the end of the map.</p>
<pre class="brush:perl">my @anchors = map { {
    class =&gt; 'standard',
    style =&gt; '',
    lang  =&gt; 'en',
    dir   =&gt; 'ltr',
    %{$_}
  } } (
  {
    text =&gt; 'Effective Perl',
    href =&gt; 'http://www.effectiveperlprogramming.com'
  },
  {
    text =&gt; 'Perl',
    href =&gt; 'http://www.perl.org'
  },
  {
    text =&gt; 'Perl Foundation',
    href =&gt; 'http://www.perlfoundation.org'
  },
  {
    text =&gt; 'Perl6 России',
    href =&gt; 'http://www.perl6.ru',
    lang =&gt; 'ru'
  },
  # ... and so on
);</pre>
<p>This simple tweak to the configuration setup significantly reduces the amount of redundancy in the code. Programmers who maintain this code can quickly see what the default values are for all of our anchor tags and can also more easily see the tags with customizations. When all of the options were specified for every anchor, it was easy to miss the meaningful configuration that made the anchors unique. There was way too much noise with the repeated code.</p>
<p>We can take our DRY&#8217;ness a step further now by removing the repeated hash keys in the configuration. Every anchor will have a different bit of text and a different link, so those keys will be present for every single configuration. Why declare them every time? Well, one reason is that it serves as good documentation. However, when you only have a couple of required options, positional notation is fine.</p>
<p>In this example, I&#8217;m storing each anchor&#8217;s configuration in an anonymous array. I&#8217;m assuming that the first two elements of the array are always the text and link for the anchor. Everything else is a customization.</p>
<pre class="brush:perl">my @anchors = map { {
    text  =&gt; shift @{$_},
    href  =&gt; shift @{$_},
    class =&gt; 'standard',
    style =&gt; '',
    lang  =&gt; 'en',
    dir  =&gt; 'ltr',
    @{$_}
  } } (
    [ 'Effective Perl' =&gt; 'http://www.effectiveperlprogramming.com' ],
    [ 'Perl' =&gt; 'http://www.perl.org' ],
    [ 'Perl Foundation' =&gt; 'http://www.perlfoundation.org' ],
    [ 'Perl6 России' =&gt; 'http://www.perl6.ru', lang =&gt; 'ru' ],
    # ... and so on
);</pre>
<p>Now the configuration is very succinct and easy to read compared to its wordy successor. There is very little noise and no repeated code. Each configured anchor is as customizable as when we started. The common elements are only mentioned once and the differences are all that we see.</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Keep+your+programmatic+configuration+DRY+http://kz974.th8.us" 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=Keep+your+programmatic+configuration+DRY+http://kz974.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/407&amp;title=Keep+your+programmatic+configuration+DRY" 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/407&amp;title=Keep+your+programmatic+configuration+DRY" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/407&amp;title=Keep+your+programmatic+configuration+DRY" 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/407&amp;title=Keep+your+programmatic+configuration+DRY" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/407&amp;t=Keep+your+programmatic+configuration+DRY" 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/407&amp;t=Keep+your+programmatic+configuration+DRY" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/407&amp;title=Keep+your+programmatic+configuration+DRY" 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/407&amp;title=Keep+your+programmatic+configuration+DRY" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/407/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Set custom DBI error handlers</title>
		<link>http://www.effectiveperlprogramming.com/blog/430</link>
		<comments>http://www.effectiveperlprogramming.com/blog/430#comments</comments>
		<pubDate>Sun, 11 Jul 2010 07:28:37 +0000</pubDate>
		<dc:creator>brian d foy</dc:creator>
				<category><![CDATA[databases]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=430</guid>
		<description><![CDATA[The DBI module lets you handle errors yourself if you don&#8217;t like its built-in behavior. DBI lets you handle the errors at either the database or the statement handle level by specifying attributes: my $dbh = DBI->connect( ..., ..., \%attr ); my $sth = $dbh->prepare( ..., \%attr ); There are several attributes that affect error [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://search.cpan.org/dist/DBI">DBI</a> module lets you handle errors yourself if you don&#8217;t like its built-in behavior. DBI lets you handle the errors at either the database or the statement handle level by specifying attributes:</p>
<pre class="brush:perl">
my $dbh = DBI->connect( ..., ..., \%attr );

my $sth = $dbh->prepare( ..., \%attr );
</pre>
<p>There are several attributes that affect error handling, each of which you can use with either a connection or a statement handle:</p>
<div align="center">
<table border="1" cellpadding="10">
<tr>
<th bgcolor="yellow">Attribute</th>
<th bgcolor="yellow">Type</th>
<th bgcolor="yellow">Default</th>
</tr>
<tr>
<td>PrintWarn</td>
<td>Boolean</td>
<td>On</td>
</tr>
<tr>
<td>PrintError</td>
<td>Boolean</td>
<td>On</td>
</tr>
<tr>
<td>RaiseError</td>
<td>Boolean</td>
<td>Off</td>
</tr>
<tr>
<td>HandleError</td>
<td>Code Ref</td>
<td>Off</td>
</tr>
<tr>
<td>ShowErrorStatement</td>
<td>Boolean</td>
<td>Off</td>
</tr>
</table>
</div>
<p>These attributes are inherited by anything derived from the handle where you set them.</p>
<p>The <code>PrintWarn</code> and <code>PrintError</code> attributes do just what they say. They are on by default, and they don&#8217;t stop your program. In this example, you prepare a statement that expects one bind parameter, but when you execute it, you give two parameters instead:</p>
<pre class="brush:perl">
use DBI;

my $dbh = DBI->connect( 'dbi:SQLite:dbname=test.db', '', '', {} );

my $sth = $dbh->prepare( 'SELECT * FROM Cats WHERE id = ?' );
$sth->execute( 1, 2 );

while( my @row = $sth->fetchrow_array ) {
	print "row: @row\n";
	}

print "Got to the end\n";
</pre>
<p>Since <code>PrintError</code> is true by default, DBI prints the error, but it allows the program to continue even though there was an error:</p>
<pre class="brush:plain">
DBD::SQLite::st execute failed: called with 2 bind variables when 1 are needed at dbi-test.pl line 12.
Got to the end
</pre>
<p>If you set the <code>ShowErrorStatement</code> attribute, you get a better error message because DBI appends the SQL statement that you tried to execute. You can set this either database handle or the statement handle, but if you don&#8217;t know which statement is causing the problem, it&#8217;s easier to set it as part of the database handle:</p>
<pre class="brush:perl">
# The rest of the program is the same
my $dbh = DBI->connect( 'dbi:SQLite:dbname=test.db', '', '', {
	ShowErrorStatement => 1,
	} );
</pre>
<p>The error message shows the SQL statement, but the program still continues:</p>
<pre class="brush:plain">
DBD::SQLite::st execute failed: called with 2 bind variables when 1 are needed [for Statement "SELECT * FROM Cats WHERE id = ?"] at dbi-test.pl line 12.
Got to the end
</pre>
<p>The <code>RaiseError</code> attribute turns errors into fatal errors that you can trap with <code><a href="http://perldoc.perl.org/functions/eval.html">eval { ... }</a></code> or <A href="http://search.cpan.org/dist/Try-Tiny">Try::Tiny</a> (<span class="item">Item 103: Handle Exceptions Properly</span>) (or not trap if you want your program to die):</p>
<pre class="brush:perl">
# The rest of the program is the same
my $dbh = DBI->connect( 'dbi:SQLite:dbname=test.db', '', '', {
	RaiseError         => 1,
	ShowErrorStatement => 1,
	} );

use Try::Tiny;

try {
	$sth->prepare( ... );
	$sth->execute( ... );
	}
catch {
	...
	};
</pre>
<p>The output shows that the program stops (there&#8217;s no &#8220;Got to the end&#8221;), but you see duplicated error messages; the one from <code>PrintError</code> that is just a warning, and the one from <code>RaiseError</code> that kills the program:</p>
<pre class="brush:plain">
DBD::SQLite::st execute failed: called with 2 bind variables when 1 are needed [for Statement "SELECT * FROM Cats WHERE id = ?"] at dbi-test.pl line 14.
DBD::SQLite::st execute failed: called with 2 bind variables when 1 are needed [for Statement "SELECT * FROM Cats WHERE id = ?"] at dbi-test.pl line 14.
</pre>
<p>Turning off <code>PrintError</code> can fix the duplication:</p>
<pre class="brush:perl">
# The rest of the program is the same
my $dbh = DBI->connect( 'dbi:SQLite:dbname=test.db', '', '', {
	PrintError         => 0,
	RaiseError         => 1,
	ShowErrorStatement => 1,
	} );
</pre>
<p>Simply raising the exception might be good enough for some applications, but sometimes you want more control of the errors. In those cases, you can handle the errors yourself by providing a code reference to <code>HandleError</code>. In this case, you can just catch the error and print it:</p>
<pre class="brush:perl">
my $dbh = DBI->connect( 'dbi:SQLite:dbname=test.db', '', '', {
	ShowErrorStatement => 1,
	HandleError        => \&#038;dbi_error_handler,
	} );

sub dbi_error_handler {
	my( $message, $handle, $first_value ) = @_;

	print "Caught: $message\n";

	return 1;
	}
</pre>
<p>DBI passes your <code>HandleError</code> three arguments: the error string it would have used with <code>PrintError</code>, the handle that generated the error, and first return value from the failing method (which is typically nothing useful since there&#8217;s an error of some sort).</p>
<p>The error message shows the you caught the error:</p>
<pre class="brush:plain">
Caught: DBD::SQLite::st execute failed: called with 2 bind variables when 1 are needed [for Statement "SELECT * FROM Cats WHERE id = ?"]
Got to the end
</pre>
<p>If you want a stack trace, you can use <a href="http://perldoc.perl.org/Carp.html">Carp</a> (and curiously, the argument alignment works out!).</p>
<pre class="brush:perl">
use Carp;

my $dbh = DBI->connect( 'dbi:SQLite:dbname=test.db', '', '', {
	ShowErrorStatement => 1,
	HandleError        => \&#038;Carp::confess,
	} );
</pre>
<p><code>HandleError</code> is how <A href="http://search.cpan.org/dist/Exception-Class-DBI">Exception::Class::DBI</a> inserts its error handler:</p>
<pre class="brush:perl">
my $dbh = DBI->connect( $dsn, $user, $pass, {
	PrintError  => 0,
	RaiseError  => 0,
	HandleError => Exception::Class::DBI->handler,
	});
</pre>
<p>The <a href="http://search.cpan.org/dist/DBIx-Log4perl">DBIx-Log4perl</a> uses <code>HandleError</code>, although it hides the details from you:</p>
<pre class="brush:perl">
my $dbh = DBIx::Log4perl->connect('dbi:Oracle:XE', 'user', 'password');
</pre>
<p>There are some things that you might want to do when handling the error yourself, depending on what you want to accomplish:</p>
<ul>
<li>rollback if you are in the middle of a transaction
<li>disconnect from the database if you are going to quit
<li>reconnect to the database if you lost the connection
<li>print a stack trace
</ul>
<p>No matter what you want to do, however, it&#8217;s <code>HandleError</code> that lets you do it.</p>
<h2>Things to remember</h2>
<ul>
<li>The <code>RaiseError</code> attribute turns DBI handle warning into fatal errors
<li>You can handle errors yourself by giving <code>HandleError</code> a code reference
<li>Setting the <code>ShowErrorStatement</code> attribute adds the offending SQL statement to the error message
</ul>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Set+custom+DBI+error+handlers+http://dw9nf.th8.us" 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=Set+custom+DBI+error+handlers+http://dw9nf.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/430&amp;title=Set+custom+DBI+error+handlers" 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/430&amp;title=Set+custom+DBI+error+handlers" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/430&amp;title=Set+custom+DBI+error+handlers" 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/430&amp;title=Set+custom+DBI+error+handlers" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/430&amp;t=Set+custom+DBI+error+handlers" 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/430&amp;t=Set+custom+DBI+error+handlers" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/430&amp;title=Set+custom+DBI+error+handlers" 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/430&amp;title=Set+custom+DBI+error+handlers" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/430/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>YAPC::NA 2010 Presentation Slides</title>
		<link>http://www.effectiveperlprogramming.com/blog/424</link>
		<comments>http://www.effectiveperlprogramming.com/blog/424#comments</comments>
		<pubDate>Sat, 10 Jul 2010 19:58:25 +0000</pubDate>
		<dc:creator>Josh McAdams</dc:creator>
				<category><![CDATA[presentations]]></category>
		<category><![CDATA[slides available]]></category>
		<category><![CDATA[talks]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=424</guid>
		<description><![CDATA[At YAPC::NA 2010, brian gave a class on Effective Perl and I gave three short presentations related to topics that we discuss in Effective Perl Programming, 2nd Edition. Links to my presentations (with notes) in PDF format (gzipped) can be found below: Continuous Integration: CruiseControl and Perl Dependency Injection: Who Cares? Effective Perl: Unicode]]></description>
			<content:encoded><![CDATA[<p>At <a title="YAPC::NA 2010" href="http://yapc2010.com/yn2010/">YAPC::NA 2010</a>, brian gave a class on Effective Perl and I gave three short presentations related to topics that we discuss in <a title="Effective Perl Programming, 2nd Edition" href="http://www.amazon.com/dp/0321496949?tag=theeffeperl-20&amp;camp=14573&amp;creative=327641&amp;linkCode=as1&amp;creativeASIN=0321496949&amp;adid=089502333VCNP2F6JD7F&amp;">Effective Perl Programming, 2nd Edition</a>. Links to my presentations (with notes) in PDF format (gzipped) can be found below:</p>
<ul>
<li><a title="Continuous Integration: CruiseControl and Perl" href="http://effectiveperlprogramming.com/presentations/YAPC_NA_2010_Continuous_Integration_CruiseControl_And_Perl.pdf.gz">Continuous Integration: CruiseControl and Perl</a></li>
<li><a title="Dependency Injection: Who Cares?" href="http://effectiveperlprogramming.com/presentations/YAPC_NA_2010_Dependency_Injection_Who_Cares.pdf.gz">Dependency Injection: Who Cares?</a></li>
<li><a title="Effective Perl: Unicode" href="http://effectiveperlprogramming.com/presentations/YAPC_NA_2010_Effective_Perl_Unicode.pdf.gz">Effective Perl: Unicode</a></li>
</ul>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=YAPC%3A%3ANA+2010+Presentation+Slides+http://p6w6b.th8.us" 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=YAPC%3A%3ANA+2010+Presentation+Slides+http://p6w6b.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/424&amp;title=YAPC%3A%3ANA+2010+Presentation+Slides" 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/424&amp;title=YAPC%3A%3ANA+2010+Presentation+Slides" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/424&amp;title=YAPC%3A%3ANA+2010+Presentation+Slides" 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/424&amp;title=YAPC%3A%3ANA+2010+Presentation+Slides" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/424&amp;t=YAPC%3A%3ANA+2010+Presentation+Slides" 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/424&amp;t=YAPC%3A%3ANA+2010+Presentation+Slides" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/424&amp;title=YAPC%3A%3ANA+2010+Presentation+Slides" 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/424&amp;title=YAPC%3A%3ANA+2010+Presentation+Slides" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/424/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Effective Perl Programming is in PDF and ePub</title>
		<link>http://www.effectiveperlprogramming.com/blog/399</link>
		<comments>http://www.effectiveperlprogramming.com/blog/399#comments</comments>
		<pubDate>Thu, 08 Jul 2010 19:14:11 +0000</pubDate>
		<dc:creator>brian d foy</dc:creator>
				<category><![CDATA[eBook]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=399</guid>
		<description><![CDATA[I just found out that Effective Perl Programming is available in digital formats through eBooks.com. They have a PDF version and an ePub version, each for $US31.99, which, sadly, is more than the hard-copy price of $US26.39 on Amazon.com and the Kindle price of $US17.59. They specifically list that these formats target Adobe Digital Editions, [...]]]></description>
			<content:encoded><![CDATA[<p>I just found out that <i>Effective Perl Programming</i> is available in <a href="http://www.ebooks.com/ebooks/book_display.asp?IID=515079">digital formats through eBooks.com</a>. They have a PDF version and an ePub version, each for $US31.99, which, sadly, is more than the hard-copy price of $US26.39 on Amazon.com and the Kindle price of $US17.59.</p>
<p>They specifically list that these formats target <a href="http://www.adobe.com/products/digitaleditions/">Adobe Digital Editions</a>, so I don&#8217;t know if they&#8217;ve checked them on any other readers or have used special features.</p>
<p><a href="http://www.informit.com/store/product.aspx?isbn=0321496949">InformIT</a> also has an &#8220;eBook&#8221; version, which I think is just a PDF, for $US28.79, but also has a &#8220;Book + eBook Bundle&#8221; for $US47.19. They might offer ePub in the future.</p>
<p>If anyone buys either the PDF or ePub versions from eBooks or InformIT, let us know what you think of them, how they look, and which reader you use.</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Effective+Perl+Programming+is+in+PDF+and+ePub+http://ybww5.th8.us" 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=Effective+Perl+Programming+is+in+PDF+and+ePub+http://ybww5.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/399&amp;title=Effective+Perl+Programming+is+in+PDF+and+ePub" 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/399&amp;title=Effective+Perl+Programming+is+in+PDF+and+ePub" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/399&amp;title=Effective+Perl+Programming+is+in+PDF+and+ePub" 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/399&amp;title=Effective+Perl+Programming+is+in+PDF+and+ePub" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/399&amp;t=Effective+Perl+Programming+is+in+PDF+and+ePub" 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/399&amp;t=Effective+Perl+Programming+is+in+PDF+and+ePub" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/399&amp;title=Effective+Perl+Programming+is+in+PDF+and+ePub" 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/399&amp;title=Effective+Perl+Programming+is+in+PDF+and+ePub" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/399/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Watch out for side effects with `use VERSION`</title>
		<link>http://www.effectiveperlprogramming.com/blog/396</link>
		<comments>http://www.effectiveperlprogramming.com/blog/396#comments</comments>
		<pubDate>Sun, 04 Jul 2010 18:49:50 +0000</pubDate>
		<dc:creator>brian d foy</dc:creator>
				<category><![CDATA[5.10]]></category>
		<category><![CDATA[5.12]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=396</guid>
		<description><![CDATA[To specify that you wanted to use at least a particular version of Perl, you specified that version with the use built-in: use VERSION; We covered this in Item 83: Limit your distributions to the right platforms, and we mentioned that it might invoke side effects. We didn&#8217;t get into the details in that Item [...]]]></description>
			<content:encoded><![CDATA[<p>To specify that you wanted to use at least a particular version of Perl, you specified that version with the <a href="http://perldoc.perl.org/functions/use.html">use</a> built-in:</p>
<pre class="brush:perl">
use VERSION;
</pre>
<p>We covered this in <span class="item">Item 83: Limit your distributions to the right platforms</span>, and we mentioned that it might invoke side effects. We didn&#8217;t get into the details in that Item though. As of Perl 5.10, this introduces side effects that you might not want.</p>
<p>Merely specifying a Perl version prior to 5.10 (well, actually before 5.9.5, the development track that led to 5.10) does nothing other than check the version you specify against the interpreter version. If the version you specify is equal to or greater than the interpreter version, your program continues. If not, it dies:</p>
<pre class="brush:perl">
use 5.008;  # needs perl5.008000 or later
</pre>
<p>This works with <a href="http://perldoc.perl.org/functions/require.html">require</a> too:</p>
<pre class="brush:perl">
require 5.008;  # needs perl5.008000 or later
</pre>
<p>However, <code>use</code> is a compile-time function and <code>require</code> is a run-time function. By the time you hit that <code>require</code>, <code>perl</code> has already compiled your program up to that point or died trying as it ran into unknown features. Code may have already run, despite using an inappropriate version of <code>perl</code>. You want to impose your version restriction as soon as possible.</p>
<p>You might think that you can fix this with a <code>BEGIN</code> block which compiles and immediately runs the code so you get the ordering right:</p>
<pre class="brush:perl">
BEGIN { require 5.010; }
</pre>
<p>However, this also pulls in the new features for that version, at least in Perls 5.10 and 5.12, although that <a href="http://rt.perl.org/rt3/Public/Bug/Display.html?id=76374">might be a bug</a>. Even if it is, it still is what it is and you need to watch out for it.</p>
<h2>use 5.010</h2>
<p>With Perl 5.10, you get three side effects with <code>use 5.010</code>. Starting with that version, <code>use</code>-ing the version also pulls in the new features for that version. Obstensibly, that keeps programs designed for earlier versions breaking as newer <code>perl</code>s add keywords, but it also tries to enforce the current philosophy of good programming on you.</p>
<p>Perl 5.10 introduces <code>say</code>, <code>state</code>, and <code>given-which</code>, which you import implicitly when you say <code>use 5.010</code>:</p>
<pre class="brush:perl">
use 5.010;
say 'I can use Switch!';  # imported say()

given ($ARGV[0]) {        # imported given()
	when( defined ) { some_sub() }
	};

sub some_sub {
	state $n = 0;         # imported state()
	say "$n: got a defined argument";
	}
</pre>
<p>If you want to insist on Perl 5.010 but not use its new features, perhaps because that&#8217;s the installation with the necessary modules, you can unimport the side effects immediately with the new <a href="http://perldoc.perl.org/">feature</a> pragma:</p>
<pre class="brush:perl">
use 5.010;     # implicit imports
no feature;    # take it right back again

# you're own version of say()
sub say {
	# something that you want to do
	}
</pre>
<p>If you only want some of the new features, you can unimport the ones that you don&#8217;t want:</p>
<pre class="brush:perl">
use 5.010;
no feature qw(say);   # leaves state() and given()

sub say {
	# something that you want to do
	}
</pre>
<h2>use 5.012</h2>
<p>Perl 5.12 includes two more side effects for <code>use VERSION</code>. The <code>unicode_strings</code> feature treats all strings outside of <code>bytes</code> and <code>locale</code> scopes as Unicode strings. Additionally, <code>use 5.012</code> automatically turns on <A href="http://perldoc.perl.org/strict.html">strict</a>:</p>
<pre class="brush:perl">
use 5.012;
# now strictures are on

$foo = 1;   # compile-time error!
</pre>
<p>Again, you can&#8217;t get around this by using <code>require</code> because it still turns on the new features and enables <code>strict</code>:</p>
<pre class="brush:perl">
BEGIN { require 5.012 }

$foo = 1;  # still a compile-time error
</pre>
<p>If, for some odd and dangerous reason you don&#8217;t want <code>strict</code> on by default, you can turn it off yourself, even though unimporting it doesn&#8217;t give you the warning that you&#8217;ve left the paved roads, you&#8217;ve just violated your rental car contract, and there&#8217;s a chainsaw massacrer waiting for you:</p>
<pre class="brush:perl">
use 5.012;
no feature;
no strict;

my $foo = 1;   

$fo0++;  # sure, go ahead and make that error
</pre>
<h2>A workaround to restrict <code>perl</code> versions</h2>
<p>There&#8217;s a way around all of this, and it&#8217;s to not restrict the version with <code>use</code> if that&#8217;s the only thing that you want to do. Instead, you can check the value of the <code>$]</code> variable, just like the various examples you saw in <span class="item">Item 83</span>:</p>
<pre class="brush:perl">
BEGIN {
	die "Unsupported version"
		unless $] >= 5.010 and $] < 5.011
	}
</pre>
<p>This has the added benefit of restricting the upper acceptable <code>perl</code> version.</p>
<h2>Things to remember</h2>
<ul>
<li><code>use VERSION</code> imports new features since Perl 5.9.5.
<li><code>BEGIN { require VERSION }</code> still imports new features
<li>Use <code>no feature</code> or <code>no strict</code> to unimport unwanted features.
<li>Restrict the <code>perl</code> version with <code>$]</code>.
</ul>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Watch+out+for+side+effects+with+%60use+VERSION%60+http://emnpe.th8.us" 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=Watch+out+for+side+effects+with+%60use+VERSION%60+http://emnpe.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/396&amp;title=Watch+out+for+side+effects+with+%60use+VERSION%60" 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/396&amp;title=Watch+out+for+side+effects+with+%60use+VERSION%60" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/396&amp;title=Watch+out+for+side+effects+with+%60use+VERSION%60" 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/396&amp;title=Watch+out+for+side+effects+with+%60use+VERSION%60" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/396&amp;t=Watch+out+for+side+effects+with+%60use+VERSION%60" 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/396&amp;t=Watch+out+for+side+effects+with+%60use+VERSION%60" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/396&amp;title=Watch+out+for+side+effects+with+%60use+VERSION%60" 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/396&amp;title=Watch+out+for+side+effects+with+%60use+VERSION%60" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/396/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>The handful of basic Perl concepts</title>
		<link>http://www.effectiveperlprogramming.com/blog/393</link>
		<comments>http://www.effectiveperlprogramming.com/blog/393#comments</comments>
		<pubDate>Fri, 02 Jul 2010 23:39:05 +0000</pubDate>
		<dc:creator>brian d foy</dc:creator>
				<category><![CDATA[classroom training]]></category>
		<category><![CDATA[yapc]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=393</guid>
		<description><![CDATA[I&#8217;ve now given the second Effective Perl Programming class, this time a two-day master class at YAPC::NA 2010 in Columbus. The common comment during the class seemed to be &#8220;You just blew my mind again&#8221;. I&#8217;m also giving this talk in a one day format at YAPC::EU in Pisa on Aug 7 Most of the [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve now given the second <i>Effective Perl Programming</i> class, this time a two-day master class at YAPC::NA 2010 in Columbus. The common comment during the class seemed to be &#8220;You just blew my mind again&#8221;. I&#8217;m also giving this talk in a one day format at <a href="http://conferences.yapceurope.org/ye2010/training_courses.html">YAPC::EU in Pisa on Aug 7</a></p>
<p>Most of the class goes back to the basics and re-learning the handful of underlying rules in Perl. These are the things that we don&#8217;t get bogged down with in <a href="http://www.amazon.com/exec/obidos/ASIN/0596520107/theperlreview-20">Learning Perl</a>, where we want to get as much Perl in front of people as soon as possible so they can start writing Perl programs (no matter how ugly they might look). <i>Effective Perl Programming</i>, however, takes that to another level as Perlers come back to think about the subtle things that they ignored while they were trying to get the big picture. Learning any language is a spiralling effort to big up the big concepts then coming back around to refine them, over and over.</p>
<p>I&#8217;ve started to make a list of the handful of things that Perlers need to understand, and none of it has to do with tricky syntax. Many people never pick up these concepts, so they come up with complicated models to explain why things happen. Instead, the Perler just needs to understand:</p>
<ul>
<li>Data and variables are different things (e.g. lists and arrays)
<li>Operators matter more than data for deciding what happens
<li>Context is important (strings and numbers; scalar, list, and void)
<li>Run-time versus compile time, and when things happen despite their location in the code
</ul>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=The+handful+of+basic+Perl+concepts+http://kxdni.th8.us" 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=The+handful+of+basic+Perl+concepts+http://kxdni.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/393&amp;title=The+handful+of+basic+Perl+concepts" 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/393&amp;title=The+handful+of+basic+Perl+concepts" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/393&amp;title=The+handful+of+basic+Perl+concepts" 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/393&amp;title=The+handful+of+basic+Perl+concepts" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/393&amp;t=The+handful+of+basic+Perl+concepts" 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/393&amp;t=The+handful+of+basic+Perl+concepts" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/393&amp;title=The+handful+of+basic+Perl+concepts" 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/393&amp;title=The+handful+of+basic+Perl+concepts" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/393/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Respect the global state of the flip flop operator</title>
		<link>http://www.effectiveperlprogramming.com/blog/314</link>
		<comments>http://www.effectiveperlprogramming.com/blog/314#comments</comments>
		<pubDate>Sun, 27 Jun 2010 15:37:40 +0000</pubDate>
		<dc:creator>brian d foy</dc:creator>
				<category><![CDATA[The Basics of Perl]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=314</guid>
		<description><![CDATA[Perl&#8217;s flip-flop operator, .., (otherwise known as the range operator in scalar context) is a simple way to choose a window on some data. It returns false until its lefthand side is true. Once the lefthand side is true, the flip-flop operator returns true until its righthand side is true. Once the righthand side is [...]]]></description>
			<content:encoded><![CDATA[<p>Perl&#8217;s flip-flop operator, <code>..</code>, (otherwise known as the range operator in scalar context) is a simple way to choose a window on some data. It returns false until its lefthand side is true. Once the lefthand side is true, the flip-flop operator returns true until its righthand side is true. Once the righthand side is true, the flip flop operator returns false. That is, the lefthand side turns it on and the righthand side turns it off.</p>
<p>Start with a simple file that has <code>START</code> and <code>END</code> markers:</p>
<pre class="brush:plain">
# input.txt
Ignore this
Ignore this too
START
Show this
And this
Also this
END
Don't show this
Or this
</pre>
<p>You need to extract the lines between those two markers:</p>
<pre class="brush:perl">
# flip-flop
while( <> ) {
	say if /START/ .. /END/;
	}
</pre>
<p>The output shows the just the stuff between those markers:</p>
<pre class="brush:plain">
% perl flip-flop input.txt
START
Show this
And this
Also this
END
</pre>
<p>What if you make the file a bit more complicated so there is an extra matching  window? Once the flip-flop operator goes back to false, it can turn to true once its lefthand side matches again. Here&#8217;s a file with two windows:</p>
<pre class="brush:plain">
# input2.txt
Ignore this
Ignore this too
START
Show this
And this
Also this
END
Don't show this
Or this
START
Show this again
And this again
Also this again
END
But ignore this
</pre>
<p>Now you get both windows of output:</p>
<pre class="brush:plain">
% perl flip-flop input2.txt
START
Show this
And this
Also this
END
START
Show this again
And this again
Also this again
END
</pre>
<p>That&#8217;s fine, but it gets a bit more complicated when you try to use the same flip flop more than once when you don&#8217;t know its state. Modify the <code>flip-flop</code> program so it goes through each file separately instead of combining all the files into the <code>ARGV</code> filehandle:</p>
<pre class="brush:perl">
foreach my $file ( @ARGV )
	{
	open my $fh, '<', $file or die "Could not find $file\n";
	while( <$fh> ) {
		say if /START/ .. /END/;
		}
	}
</pre>
<p>To watch it work (or not work, coming later), split the <i>input2a.txt</i> file into two separate files, each of which has its own window you want to extract:</p>
<pre class="brush:plain">
# input2a.txt
Ignore this
Ignore this too
START
Show this
And this
Also this
END
Don't show this
</pre>
<pre class="brush:plain">
# input2b.txt
Or this
START
Show this again
And this again
Also this again
END
But ignore this
</pre>
<p>The output isn&#8217;t surprising and it looks the same as it did with the previous program:</p>
<pre class="brush:plain">
% perl flip-flop input2a.txt input2b.txt
START
Show this
And this
Also this
END
START
Show this again
And this again
Also this again
END
</pre>
<p>However, it&#8217;s at this point that some people get confused. The flip-flip operator doesn&#8217;t care about which file you are looking at, what happened in the last file, and so on. To see it &#8220;break&#8221;, change <i>input2a.txt</i> to it doesn&#8217;t have the <code>END</code> marker:</p>
<pre class="brush:plain">
# input2a.txt
Ignore this
Ignore this too
START
Show this
And this
Also this
Don't show this
</pre>
<p>Since <i>input2a.txt</i> doesn&#8217;t complete the window as you intended, the flip-flop, maintaining its state, is still true when it starts the second file:</p>
<pre class="brush:plain">
% perl flip-flop input2a.txt input2b.txt
START
Show this
And this
Also this
Don't show this
# inputb.txt
Or this
START
Show this again
And this again
Also this again
END
</pre>
<p>The flip-flop maintains its global state. It doesn&#8217;t care about starting new loops, new iterations, or anything else. You might think that you could find that in a subroutine, but it&#8217;s not even safe there. Every flip-flop operator that <code>perl</code> compiles has its own state, and <code>perl</code> compiles a subroutine only once:</p>
<pre class="brush:perl">
foreach my $file ( @ARGV )
	{
	open my $fh, '<', $file or die "Could not find $file\n";
	extract( $fh );
	}

sub extract {
	my( $fh ) = shift;

	while( <$fh> ) {
		print if /START/ .. /END/; # this is the same .. on every call
		}
	}
</pre>
<p>The output doesn&#8217;t change! The flip-flop doesn&#8217;t really care that it&#8217;s in a subroutine. It&#8217;s really just the same flip-flop like it was before.</p>
<p>So, if every flip-flop operator that <code>perl</code> compiles has its own state, and you want a flip-flop operator with a new state, you just need to compile a new flip-flop for each iteration. That&#8217;s simple enough, kinda. This program won&#8217;t work because the subroutine reference is the same each time. When <code>perl</code> compiles it, it knows that the anonymous subroutine is going to be the same each time so <code>perl</code> reuses it: </p>
<pre class="brush:perl">
foreach my $file ( @ARGV )
	{
	open my $fh, '<', $file or die "Could not find $file\n";
	make_extractor()->($fh);
	}

sub make_extractor {
	sub { # only compiled once
		my( $fh ) = shift;

		while( <$fh> ) {
			print if /START/ .. /END/;
			}
		};
	}
</pre>
<p>You can verify this by dumping the return value of <code>make_extractor</code>:</p>
<pre class="brush:perl">
# dump-subs.pl
use Devel::Peek;

my @subs = map { make_extractor() } 1 .. 3;

print Dump( $_ ) foreach @subs;

sub make_extractor {
	sub { # only compiled once
		my( $fh ) = shift;

		while( <$fh> ) {
			print if /START/ .. /END/;
			}
		};
	}
</pre>
<p>You get the same subroutine each time, which means you get the same flip-flop each time:</p>
<pre class="brush:plain">
% perl dump-subs.pl
SV = RV(0x80f66c) at 0x80f660
  REFCNT = 2
  FLAGS = (ROK)
  RV = 0x81a4f0
  SV = PVCV(0x80e4b8) at ...
SV = RV(0x80f6fc) at 0x80f6f0
  REFCNT = 2
  FLAGS = (ROK)
  RV = 0x81a4f0
  SV = PVCV(0x80e4b8) ...
SV = RV(0x8030bc) at 0x8030b0
  REFCNT = 2
  FLAGS = (ROK)
  RV = 0x81a4f0
  SV = PVCV(0x80e4b8) ...
</pre>
<p>You have to make each subroutine different somehow. The trick is to use a closure, which is a subroutine that references a lexical variable that has gone out of scope. In this case, you can enlist <code>state</code> to keep track of how many flip-flop operators you make, and since each new anonymous subroutine needs to capture the value of <code>$count</code>, <code>perl</code> can&#8217;t reuse previous definitions. You force it to make a new subroutine:</p>
<pre class="brush:perl">
# flip-flop
use 5.010;

foreach my $file ( @ARGV )
	{
	open my $fh, '<', $file or die "Could not find $file\n";
	make_extractor()->($fh);
	}

sub make_extractor {
	state $count = 0;
	$count++;

	sub {
		my( $fh ) = shift;

		while( <$fh> ) {
			print "$count: $_" if /START/ .. /END/;
			}
		};
	}
</pre>
<p>Now each file gets its own flip-flop. You can see where the first file ends (and is missing its marker) and the second file begins. Every file gets its own flip-flop:</p>
<pre class="brush:plain">
% perl flip-flop input2a.txt input2b.txt
1: START
1: Show this
1: And this
1: Also this
1: Don't show this
2: START
2: Show this again
2: And this again
2: Also this again
2: END
</pre>
<p>For more information about flip-flops, see <a href="http://perldoc.perl.org/perlop.html#Range-Operators">perlop&#8217;s entry for Range Operators</a>.</p>
<h2>Things to remember</h2>
<ul>
<li>Every flip-flop maintains a global state
<li>Flip-flops are not scoped
<li>Create a new flip-flop by wrapping it in a closure
</ul>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Respect+the+global+state+of+the+flip+flop+operator+http://c44g9.th8.us" 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=Respect+the+global+state+of+the+flip+flop+operator+http://c44g9.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/314&amp;title=Respect+the+global+state+of+the+flip+flop+operator" 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/314&amp;title=Respect+the+global+state+of+the+flip+flop+operator" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/314&amp;title=Respect+the+global+state+of+the+flip+flop+operator" 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/314&amp;title=Respect+the+global+state+of+the+flip+flop+operator" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/314&amp;t=Respect+the+global+state+of+the+flip+flop+operator" 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/314&amp;t=Respect+the+global+state+of+the+flip+flop+operator" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/314&amp;title=Respect+the+global+state+of+the+flip+flop+operator" 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/314&amp;title=Respect+the+global+state+of+the+flip+flop+operator" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/314/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Detect regular expression match variables in your code</title>
		<link>http://www.effectiveperlprogramming.com/blog/140</link>
		<comments>http://www.effectiveperlprogramming.com/blog/140#comments</comments>
		<pubDate>Sun, 20 Jun 2010 04:10:32 +0000</pubDate>
		<dc:creator>Josh McAdams</dc:creator>
				<category><![CDATA[debugging]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[regular expressions]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=140</guid>
		<description><![CDATA[In Item 33: &#8220;Watch out for match variables, you found out that the match variable $`, $&#038;, and $` come with a performance hit. With all of the module code that you might use, you might be using those variables even though you didn&#8217;t code with them yourself. There&#8217;s a module that can tell you [...]]]></description>
			<content:encoded><![CDATA[<p>In <span class="item">Item 33: &#8220;Watch out for match variables</span>, you found out that the match variable <code>$`</code>, <code>$&#038;</code>, and <code>$`</code> come with a performance hit. With all of the module code that you might use, you might be using those variables even though you didn&#8217;t code with them yourself.</p>
<p>There&#8217;s a module that can tell you if anything in your program used one of these nasty variables. The <a href="http://search.cpan.org/dist/Devel-SawAmpersand">Devel::SawAmpersand</a> module uses the <code>B</code> backend to look for any compiled Perl code that deals with the internal <code>sawampersand</code> variable that, when true, automatically slows down all of your matches and substitutions. By inserting a couple of lines in at the top of your code, you can tell if <code>Perl</code> ran into <code>sawampersand</code>:</p>
<pre class="brush:perl">
use Devel::SawAmpersand qw(sawampersand);
END { print "saw ampersand => ", sawampersand(), "\n" }

my $string = 'cat bird dog';

$string =~ m/\s*bird\s*/;

print <<"HERE";
\$`  =>  $`
\$&#038;  =>  $&#038;
\$'  =>  $'
HERE
</pre>
<p>The output shows you that it did indeed see at least one of those variables:</p>
<pre class="brush:perl">
$`  =>  cat
$&#038;  =>   bird
$'  =>  dog
saw ampersand => 1
</pre>
<p>That&#8217;s not very useful because it doesn&#8217;t tell you where it found the variables, and you had to change the source to find out. You really want to do this without changing the source and also have it tell you in which files and on which line numbers those variables appear. That&#8217;s what <a href="http://search.cpan.org/dist/Devel-SawAmpersand">Devel::FindAmpersand</a> does:</p>
<pre class="brush:perl">
my $string = 'cat bird dog';

$string =~ m/\s*bird\s*/;

print <<"HERE";
\$`  =>  $`
\$&#038;  =>  $&#038;
\$'  =>  $'
HERE
</pre>
<p>Now I run the program by loading the <code>Devel::FindAmpersand</code> module on the command line (in this case, reporting the line number where the string starts):</p>
<pre class="brush:plain">
$ perl5.10.1 -MDevel::FindAmpersand amp.pl
$`  =>  cat
$&#038;  =>   bird
$'  =>  dog
Found evil variable $` in file amp.pl, line 5
Found evil variable $&#038; in file amp.pl, line 5
Found evil variable $' in file amp.pl, line 5
</pre>
<p>That&#8217;s fine for finding the variables in the same file, but what if they are in a different module? <code>Devel::FindAmpersand</code> only reports what it finds in the main script. Here&#8217;s a script that pulls in a library that uses one of the match variables:</p>
<pre class="brush:perl">
require 'uses-amp.pl';

my $string = 'cat bird dog';

$string =~ m/\s*bird\s*/;

print "Pre-match is $PREMATCH\n";
</pre>
<p>Here&#8217;s the tiny culprit library:</p>
<pre class="brush:perl">
# this is a naughty module

my $matched = $&#038;;

1;
</pre>
<p><code>Devel::FindAmpersand</code> doesn&#8217;t complain though, since the <code>$&#038;</code> doesn&#8217;t appear in the main file:</p>
<pre class="brush:plain">
$ perl -MDevel::FindAmpersand amp.pl
Pre-match is cat
</pre>
<p>Since you&#8217;re really only doing this during development and probably infrequently, you can rig a solution to search through any loaded files. Create a small module that uses an <code>END</code> block to go through all of the files listed in <code>%INC</code> and examine each individually:</p>
<pre class="brush:perl">
# ScanAmpersand.pm
END {
	foreach my $file ( values %INC ) {
		system $^X, '-MDevel::FindAmpersand', $file;
		}
	}

1;
</pre>
<p>When you use your <code>ScanAmpersand</code>, you get warnings from any files that used one of the variables:</p>
<pre class="brush:plain">
$ perl -MScanAmpersand amp.pl
Pre-match is cat
Found evil variable $&#038; in file uses-amp.pl, line 3
</pre>
<h2>Workarounds</h2>
<p>Now that you&#8217;ve found the naughty uses of <code>$`</code>, <code>$&#038;</code>, and <code>$`</code>, you need to fix up the code to remove them. If you are using Perl 5.10 or later, use the per-match variables instead (<span class="item">Item 33: Watch out for match variables</a>). If you are using a version earlier than Perl 5.10, you might modify the regular expression to explicitly capture parts of it. The <code>Devel::SawAmpersand</code> documentation gives you these possibilities:</p>
<div align="center">
<table cellpadding="15" border="1">
<tr>
<td bgcolor="yellow">Naughty</td>
<td bgcolor="yellow">Nice</td>
</tr>
<tr>
<td><code>$`</code>   of   <code>/pattern/</code></td>
<td><code>$1</code>   of  <code>/(.*?)pattern/s</code></td>
</tr>
<tr>
<td><code>$&#038;</code>   of   <code>/pattern/</code></td>
<td><code>$1</code>   of  <code>/(pattern)/</code></td>
</tr>
<tr>
<td><code>$'</code>   of   <code>/pattern/</code></td>
<td><code>$+</code>   of  <code>/pattern(.*)/s</code></td>
</tr>
</table>
</div>
<h2>Things to remember</h2>
<ul>
<li>The match variables <code>$`</code>, <code>$&#038;</code>, and <code>$`</code> suffer performance hits
<li>You don&#8217;t have to use them directly to suffer
<li>Use <code>Devel::FindAmpersand</code> to trach down their use.
</ul>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Detect+regular+expression+match+variables+in+your+code+http://6ztt9.th8.us" 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=Detect+regular+expression+match+variables+in+your+code+http://6ztt9.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/140&amp;title=Detect+regular+expression+match+variables+in+your+code" 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/140&amp;title=Detect+regular+expression+match+variables+in+your+code" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/140&amp;title=Detect+regular+expression+match+variables+in+your+code" 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/140&amp;title=Detect+regular+expression+match+variables+in+your+code" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/140&amp;t=Detect+regular+expression+match+variables+in+your+code" 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/140&amp;t=Detect+regular+expression+match+variables+in+your+code" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/140&amp;title=Detect+regular+expression+match+variables+in+your+code" 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/140&amp;title=Detect+regular+expression+match+variables+in+your+code" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/140/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Effective Perl Programming at YAPC::NA 2010</title>
		<link>http://www.effectiveperlprogramming.com/blog/375</link>
		<comments>http://www.effectiveperlprogramming.com/blog/375#comments</comments>
		<pubDate>Wed, 16 Jun 2010 06:50:16 +0000</pubDate>
		<dc:creator>brian d foy</dc:creator>
				<category><![CDATA[classroom training]]></category>
		<category><![CDATA[yapc]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=375</guid>
		<description><![CDATA[I&#8217;ll be teaching an Effective Perl Programming course at YAPC::NA in Columbus, OH on June 24 and 25 at the conference venue. The cost of the two day master class is just $240, and this year that includes your snacks and lunches each day. Josh and I will also have a box of signed copies [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ll be teaching an <a href="http://yapc2010.com/yn2010/wiki?node=Training">Effective Perl Programming course at YAPC::NA</a> in Columbus, OH on June 24 and 25 at the conference venue. The cost of the two day master class is just $240, and this year that includes your snacks and lunches each day. </p>
<p>Josh and I will also have a box of signed copies of the book, although those might go fast during the conference (and aren&#8217;t part of the course fee). Of course, you can also buy your book in advance and have us sign it during the conference. <img src='http://www.effectiveperlprogramming.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Effective+Perl+Programming+at+YAPC%3A%3ANA+2010+http://8m7qg.th8.us" 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=Effective+Perl+Programming+at+YAPC%3A%3ANA+2010+http://8m7qg.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/375&amp;title=Effective+Perl+Programming+at+YAPC%3A%3ANA+2010" 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/375&amp;title=Effective+Perl+Programming+at+YAPC%3A%3ANA+2010" title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/375&amp;title=Effective+Perl+Programming+at+YAPC%3A%3ANA+2010" 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/375&amp;title=Effective+Perl+Programming+at+YAPC%3A%3ANA+2010" title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/375&amp;t=Effective+Perl+Programming+at+YAPC%3A%3ANA+2010" 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/375&amp;t=Effective+Perl+Programming+at+YAPC%3A%3ANA+2010" title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/375&amp;title=Effective+Perl+Programming+at+YAPC%3A%3ANA+2010" 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/375&amp;title=Effective+Perl+Programming+at+YAPC%3A%3ANA+2010" title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/375/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Know when and when not to write networking code.</title>
		<link>http://www.effectiveperlprogramming.com/blog/154</link>
		<comments>http://www.effectiveperlprogramming.com/blog/154#comments</comments>
		<pubDate>Sun, 13 Jun 2010 04:38:19 +0000</pubDate>
		<dc:creator>Josh McAdams</dc:creator>
				<category><![CDATA[networking]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=154</guid>
		<description><![CDATA[Even though Perl has support for low-level socket programming, that doesn&#8217;t mean that you have to program at the low-level. For common protocols such as FTP, HTTP, POP3, or SMTP, you can use modules that come with Perl to handle the transport details. libnet, the distribution that comprises the basic protocols, comes with Perl since [...]]]></description>
			<content:encoded><![CDATA[<p>Even though Perl has support for low-level socket programming, that doesn&#8217;t mean that you have to program at the low-level. For common protocols such as FTP, HTTP, POP3, or SMTP, you can use modules that come with Perl to handle the transport details. <a href="http://search.cpan.org/dist/libnet">libnet</a>, the distribution that comprises the basic protocols, comes with Perl since 5.8. Many other protocols, such as SSH, have implementations on CPAN. You can also install from CPAN many higher level libraries, such as <a href="http://search.cpan.org/dist/libwww-perl">LWP</a> and <a href="http://search.cpan.org/dist/WWW-Mechanize">WWW::Mechanize</a>.</p>
<p>There are several reasons to avoid as much low-level work as you can. The foremost reason is that widely-used and heavily-tested libraries have not already made all of the mistakes that you are bound to make, but they&#8217;ve almost certainly fixed them. They probably handle all of the edge cases that you don&#8217;t even know about, so when your architecture changes, those widely-used modules easily handle the new setup. Is your hand-rolled code to talk to a remote server going to easily handle a proxy or SOCKS setup, or be able to switch from an unencrypted channel to SSL? </p>
<p>Unless you&#8217;re the sort of person who likes working in the low-level details, you&#8217;re simply wasting your time be reinventing the wheel. If you think your wheel is amazingly better, but you have to remember a lot of people think that. If you have the energy, consider contributing to your enthusiasm to the existing CPAN libraries.</p>
<p>As with everything in <i>The Effective Perl</i>, this isn&#8217;t a hard and fast rule. For some things, the higher level libraries don&#8217;t give you full access to the protocol, so you do need to work at a lower level.</p>
<p>Enough of that. You may still need some examples. These give you the flavor of what&#8217;s available, but that doesn&#8217;t mean they are appropriate for your particular situation. As with all modules, use them when they make sense and don&#8217;t use them when they don&#8217;t.</p>
<h2>Simple file downloading</h2>
<p><a href="http://search.cpan.org/dist/libwww-perl">LWP::Simple</a> can handle simple downloads for you:</p>
<pre class="brush:perl">
use LWP::Simple;
my $page = get( 'http://www.perlfoundation.org/' );
</pre>
<p>That&#8217;s simple enough, but what if you need to store that resource somewhere? There&#8217;s an app for that:</p>
<pre class="brush:perl">
use LWP::Simple;
getstore( 'http://www.perlfoundation.org/', 'tpf-index.html' );
</pre>
<p>This also works with FTP and many other protocols. <a href="http://search.cpan.org/dist/libwww-perl">LWP</a> actually handles many other protocols that you might not consider to be part of the World Wide Web. Perhaps you need to fetch some images from a NASA FTP server:</p>
<pre class="brush:perl">
use LWP::Simple;
getstore(
	'ftp://nssdcftp.gsfc.nasa.gov/photo_gallery/hi-res/planetary/moon/gal_moon_color.tiff',
	'awesome-moon.tiff'
	);
</pre>
<h2>Sending email</h2>
<p>There are many CPAN modules that can help you send email, and <a href="http://search.cpan.org/dist/Email-Send">Email::Send</a> is a general interface to many of them. In the constructor, you specify the implementor, in this case, <code>SMTP</code>, and the arguments to the implementor. <code>Email::Send</code> takes care of the rest:</p>
<pre class="brush:perl">
use Email::Send;

my $message = <<'EMAIL';
To: buster@example.com
From: me@example.com
Subject: I'm letting Email::Send send this

I did almost nothing to send this email.
EMAIL

my $sender = Email::Send->new({
	mailer      => 'SMTP',
	mailer_args => [ Host   => 'smtp.example.com' ],
	});

my $rc = $sender->send( $message );
unless( $rc ) {
	warn "Problem sending mail! $rc\n";
	}
else {
	print "Send mail just fine.\n";
	}
</pre>
<p>Unfortunately, <code>Email::Send</code> is superceded by <a href="http://search.cpan.org/dist/Email-Simple">Email::Simple</a>, but here&#8217;s the same program:</p>
<pre class="brush:perl">
use Email::Sender::Simple qw(sendmail);
use Email::Simple;
use Email::Simple::Creator; # an Email::Simple mixin
use Email::Sender::Transport::SMTP;

my $transport = Email::Sender::Transport::SMTP->new({
	host => 'smtp.example.com', # you can also set this in %ENV
	});

my $email = Email::Simple->create(
	header => [
		To      => '"Buster Bean" <buster@example.com>',
		From    => '"Mimi Bean" <mimi@example.com>',
		Subject => "Thanks for all the fish",
	],

	body => "I'm sending this with Email::Simple.\n",
	);

my $rc = eval { sendmail(
	$email,
	{ transport => $transport }
	) };

unless( $rc ) {
	warn "Problem sending mail! $@\n";
	}
else {
	print "Send mail just fine.\n";
	}
</pre>
<p>This &#8220;simpler&#8221; version is under active development, but it goes against most of the points we want to stress: you shouldn&#8217;t have to think about what most of this is doing or how email actually works, just like you don&#8217;t have to understand internal combustion to drive a car.</p>
<h2>Programmatic control of a web browser</h2>
<p><code>LWP</code> is sufficient for simple web tasks, but when you have to interact with forms, click through several pages, and handle other actions you might expect from an interactive browser, <a href="http://search.cpan.org/dist/WWW-Mechanize">WWW::Mechanize</a> is the tool you should you. It tracks your path through a website, handles cookies, and lets you select and follow links.</p>
<p>Here&#8217;s an example that takes a module name, a starting line number, and an ending line number. It goes through these steps:</p>
<ul>
<li>queries <a href="http://search.cpan.org/">CPAN Search</a> for the module,
<li>finds the right link in the search results</p>
<li>follows the module link
<li>looks for the &#8220;Source&#8221; link on that page
<li>gets the content of that page
<li>extract that line range
</ul>
<pre class="brush:perl">
use WWW::Mechanize;

my( $module, $start_line, $end_line ) = @ARGV;
print "Looking for $module lines $start_line to $end_line\n";

my $mech = WWW::Mechanize->new;

$mech->get( 'http://search.cpan.org' );

$mech->submit_form(
	form_number => 1,
	fields      => {
		query   => $module,
		mode    => 'module',
		}
	);

my $module_links_ref = $mech->find_link( text => $module )
	or die "Did not find $module link\n";
$mech->get( $module_links_ref->[0] );

$mech->follow_link( text_regex => qr/\ASource\z/ )

my $content = $mech->content;

open my( $fh ), '<', \ $content;

while( <$fh> ) {
	next unless $. == $start_line .. $. == $end_line;
	printf "%d: %s", $., $_;
	}
</pre>
<p>You can run this program to get an extract of some lines from <a href="http://search.cpan.org/dist/HTTP-Size">HTTP::Size</a>:</p>
<pre class="brush:perl">
$ perl mech HTTP::Size 10 20
Looking for HTTP::Size lines 10 to 20
10:
11: =head1 SYNOPSIS
12:
13:     use HTTP::Size
14:
15:     my $size = HTTP::Size::get_size( $url );
16:
17:     if( defined $size )
18:             {
19:             print "$url size was $size";
20:             }
</pre>
<p>This is only a small taste of the sorts of things that <code>WWW::Mechanize</code> can do.</p>
<h2>Downloading new files from an FTP server</h2>
<p>Sometimes you need to use a lower-level interface. For instance, if you want to sync a local directory with a remote FTP directory, you can use <a href="http://perldoc.perl.org/Net/FTP.html">Net::FTP</a> to connect to the remote directory, get the list of files in that directory, compare the modification time of the local file with the modification time, and download files that are newer on the remote side:</p>
<pre class="brush:perl">
use Net::FTP;

my $host = 'nssdcftp.gsfc.nasa.gov';

my $ftp = Net::FTP->new( $host, Debug => 0 )
	or die "Cannot connect to $host: $@";

$ftp->login("anonymous",'-anonymous@')
	or die "Cannot login: ", $ftp->message;

$ftp->cwd( '/photo_gallery/hi-res/planetary/moon' );

foreach my $file ( $ftp->ls ) {
	if( (stat($file))[9] < $ftp->mdtm( $file )  ) {
		print "Fetching $file...\n";
		$ftp->get( $file );
		}
	else {
		print "$file up-to-date\n";
		}

	}
</pre>
<p>In this case, the <code>Net::FTP</code> module is the appropriate level of coding. You don&#8217;t have to deal with the FTP protocol directly, but you have enough flexibility to deal with the features that the protocol provides.</p>
<h2>Low-level sockets</h2>
<p>Perl has the built-in interface so you can minutely control TCP and UDP sockets if that&#8217;s what you need to do. However, since we&#8217;re trying to convince you not to do that, we&#8217;ll leave those bits as an exercise for the reader.</p>
<h2>Things to remember</h2>
<ul>
<li>Work at the highest level possible and reasonable
<li>Use one of the popular CPAN modules instead of reinventing your own.
<li>Don&#8217;t create your own low-level implementations
</ul>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Know+when+and+when+not+to+write+networking+code.+http://8t5p6.th8.us" 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=Know+when+and+when+not+to+write+networking+code.+http://8t5p6.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/154&amp;title=Know+when+and+when+not+to+write+networking+code." 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/154&amp;title=Know+when+and+when+not+to+write+networking+code." title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/154&amp;title=Know+when+and+when+not+to+write+networking+code." 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/154&amp;title=Know+when+and+when+not+to+write+networking+code." title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/154&amp;t=Know+when+and+when+not+to+write+networking+code." 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/154&amp;t=Know+when+and+when+not+to+write+networking+code." title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/154&amp;title=Know+when+and+when+not+to+write+networking+code." 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/154&amp;title=Know+when+and+when+not+to+write+networking+code." title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/154/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Use Carp::REPL as an interactive Perl shell.</title>
		<link>http://www.effectiveperlprogramming.com/blog/157</link>
		<comments>http://www.effectiveperlprogramming.com/blog/157#comments</comments>
		<pubDate>Sun, 06 Jun 2010 04:39:45 +0000</pubDate>
		<dc:creator>Josh McAdams</dc:creator>
				<category><![CDATA[debugging]]></category>

		<guid isPermaLink="false">http://www.effectiveperlprogramming.com/?p=157</guid>
		<description><![CDATA[Wouldn&#8217;t it be great if you could stop your program right before it died so you could see what&#8217;s causing the problem? You could start the Perl debugger and step your way to the problem, or set up some break points, but that&#8217;s often too much work. The Carp::REPL module let&#8217;s you drop into a [...]]]></description>
			<content:encoded><![CDATA[<p>Wouldn&#8217;t it be great if you could stop your program right before it died so you could see what&#8217;s causing the problem? You could start the Perl debugger and step your way to the problem, or set up some break points, but that&#8217;s often too much work. The <a href="http://search.cpan.org/dist/Carp-REPL">Carp::REPL</a> module let&#8217;s you drop into a debugger just at the point you need.</p>
<p>Before you get too far, take a look at <A href="http://search.cpan.org/dist/Devel-REPL">Devel::REPL</a>, which <code>Carp::REPL</code> is based on. It&#8217;s a basic Read-Evaluate-Print Loop for Perl. You enter a line of Perl then the REPL evaluates it and prints the result. </p>
<p>You can start the REPL from the command line:</p>
<pre class="brush:plain">
perl -MDevel::REPL -e 'Devel::REPL->new->run'
</pre>
<p>Devel::REPL also installs an <code>re.pl</code> that you can use, but it&#8217;s not too hard to write your own, especially if you&#8217;d like to remind yourself how to get out of the REPL:</p>
<pre class="brush:perl">
use Devel::REPL;

print "Starting a Devel::REPL setting. Type exit to stop\n";

my $repl = Devel::REPL->new;
$repl->load_plugin($_) for qw(History LexEnv MultiLine::PPI);
$repl->run;
</pre>
<p>Run <code>repl</code> and try some Perl expressions. Notice that you get both the output from <code>print</code> or <code>say</code> as well as the result of the <code>print</code> or <code>say</code> (normally 1):</p>
<pre class="brush:plain">
Starting a Devel::REPL setting. Type exit to stop
$ my $string = 'The Effective Perler'
The Effective Perler
$ say $string
The Effective Perler
1
$ substr( $string, 9, 4 )
tive
$ substr( $string, 14, 4 )
Perl
$ $$
66461
$ $string =~ /Perl/
1
$ $string =~ /Ruby/
$ $string =~ /(P\S+)/
Perler
$ $string
The Effective Perler
$ localtime
16 32 2 16 4 110 0 135 1
$ time
1273995160
$ use List::Util qw(sum)
$ sum( 1 .. 1000 )
500500
$ my $sub = sub {
> my $x = shift;
> print $x*2;
> }
CODE(0xa66990)
$ $sub->(4)
8
1
</pre>
<p>That&#8217;s nice to try out some short Perl code and isolated expressions, but you&#8217;d like to be able to do that somewhere in the middle of a big program. That&#8217;s where <code>Carp::REPL</code> comes in. It installs a <code>DIE</code> handler that invokes <code>Devel::REPL</code>.</p>
<p>Here&#8217;s a small script that sometimes dies, and although Perl tells you why, pretend that it doesn&#8217;t:</p>
<pre class="brush:perl">
#!/Users/brian/bin/perl5.10.1

use 5.010;

my( $arg1, $arg2 ) = @ARGV;

my $quotient = divide( $arg1, $arg2 );

say "quotient is $quotient";

sub divide { $_[0] / $_[1] }
</pre>
<p>Here&#8217;s a couple of runs:</p>
<pre class="brush:plain">
$ perl divide 1 2
quotient is 0.5
$ perl divide 1 0
Illegal division by zero at divide.pl line 7.
</pre>
<p>To track down the error, load <code>Carp::REPL</code> from the command line and run the program. Instead of killing the program, the runtime error triggers an interactive shell so you can explore the problem:</p>
<pre class="brush:plain">
$ perl -MCarp::REPL divide.pl 1 0
Illegal division by zero at divide.pl line 11.

Trace begun at divide.pl line 11
main::divide(1, 0) called at divide.pl line 7
$
</pre>
<p>Okay, so what now? You&#8217;re at line 7, but what is that? Look around with <code>:l</code>:</p>
<pre class="brush:plain">
$ :l
  6:
  7: my $quotient = divide( $arg1, $arg2 );
  8:
  9: say "quotient is $quotient";
 10:
*11: sub divide { $_[0] / $_[1] }
</pre>
<p>Once you see that line 11 is the division, and you need to handle that better. You can redefine <code>divide</code> (the result is the subroutine definition <code>*main::divide</code>) and try again using the same arguments:</p>
<pre class="brush:plain">
$  *divide = sub { eval { $_[0] / $_[1] } // 'NaN' }
Subroutine main::divide redefined at (eval 266) line 21, <FIN> line 6.
*main::divide
$ divide( $arg1, $arg2 )
NaN
</pre>
<p>Now <code>divide</code> works! Since <code>Carp::REPL</code> comes in as your program is already <code>die</code>-ing, you don&#8217;t have a chance to pick up where you left off unless your code is already set up to recover from a <code>die</code>, such as with an <code>eval</code> block.</p>
<p>There&#8217;s a lot more that you can do with <code>Carp::REPL</code>. You can set a warn handler instead so you can drop into the REPL when your program emits a warning:</p>
<pre class="brush:plain">
$ perl -MCarp::REPL=warn some_program
</pre>
<p>You can also debug your test files by dropping into the REPL when a test fails:</p>
<pre class="brush:plain">
$ perl -Mblib -MCarp::REPL=test t/test.t
</pre>
<p>Besides the very basics that you see here, <code>Carp::REPL</code> can do much more through its various plugins. If you don&#8217;t find a plugin that you like, you can write your own.</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Use+Carp%3A%3AREPL+as+an+interactive+Perl+shell.+http://dtqfe.th8.us" 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+Carp%3A%3AREPL+as+an+interactive+Perl+shell.+http://dtqfe.th8.us" title="Post to Twitter"> </a> <a class="tt" href="http://delicious.com/post?url=http://www.effectiveperlprogramming.com/blog/157&amp;title=Use+Carp%3A%3AREPL+as+an+interactive+Perl+shell." 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/157&amp;title=Use+Carp%3A%3AREPL+as+an+interactive+Perl+shell." title="Post to Delicious"> </a> <a class="tt" href="http://digg.com/submit?url=http://www.effectiveperlprogramming.com/blog/157&amp;title=Use+Carp%3A%3AREPL+as+an+interactive+Perl+shell." 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/157&amp;title=Use+Carp%3A%3AREPL+as+an+interactive+Perl+shell." title="Post to Digg"> </a> <a class="tt" href="http://www.facebook.com/share.php?u=http://www.effectiveperlprogramming.com/blog/157&amp;t=Use+Carp%3A%3AREPL+as+an+interactive+Perl+shell." 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/157&amp;t=Use+Carp%3A%3AREPL+as+an+interactive+Perl+shell." title="Post to Facebook"> </a> <a class="tt" href="http://reddit.com/submit?url=http://www.effectiveperlprogramming.com/blog/157&amp;title=Use+Carp%3A%3AREPL+as+an+interactive+Perl+shell." 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/157&amp;title=Use+Carp%3A%3AREPL+as+an+interactive+Perl+shell." title="Post to Reddit"> </a></p>]]></content:encoded>
			<wfw:commentRss>http://www.effectiveperlprogramming.com/blog/157/feed</wfw:commentRss>
		<slash:comments>0</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[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://kp7wp.th8.us" 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://kp7wp.th8.us" 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>0</slash:comments>
		</item>
	</channel>
</rss>
