<?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"
	>

<channel>
	<title>genehack.org</title>
	<atom:link href="http://www.genehack.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.genehack.org</link>
	<description>purveyor of fine links since 1998</description>
	<pubDate>Fri, 14 Mar 2008 10:03:55 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>The first thing we do, let&#8217;s kill all the spammers</title>
		<link>http://www.genehack.org/2008/03/14/the-first-thing-we-do-lets-kill-all-the-spammers/</link>
		<comments>http://www.genehack.org/2008/03/14/the-first-thing-we-do-lets-kill-all-the-spammers/#comments</comments>
		<pubDate>Fri, 14 Mar 2008 10:03:55 +0000</pubDate>
		<dc:creator>genehack</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.genehack.org/2008/03/14/the-first-thing-we-do-lets-kill-all-the-spammers/</guid>
		<description><![CDATA[My mail filter report from yesterday:

  Total  Number Folder
  -----  ------ ------
  35457       5 .BOUNCES/
12131742    3090 .SPAM/
1957617     184 .maildir/
  -----  ------
14124816    3279

Yes kids, over 3000 mails and 95% spam! Thank Ghu for [...]]]></description>
			<content:encoded><![CDATA[<p>My mail filter report from yesterday:</p>
<pre>
  Total  Number Folder
  -----  ------ ------
  35457       5 .BOUNCES/
12131742    3090 .SPAM/
1957617     184 .maildir/
  -----  ------
14124816    3279
</pre>
<p>Yes kids, over 3000 mails and 95% spam! Thank Ghu for <a href="http://spamassassin.apache.org/">SpamAssassin</a>&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.genehack.org/2008/03/14/the-first-thing-we-do-lets-kill-all-the-spammers/feed/</wfw:commentRss>
		</item>
		<item>
		<title>couple quick links</title>
		<link>http://www.genehack.org/2008/03/13/couple-quick-links/</link>
		<comments>http://www.genehack.org/2008/03/13/couple-quick-links/#comments</comments>
		<pubDate>Thu, 13 Mar 2008 10:23:50 +0000</pubDate>
		<dc:creator>genehack</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.genehack.org/2008/03/13/couple-quick-links/</guid>
		<description><![CDATA[
Voting in first round of Beer Madness now open
USENIX makes old proceedings freely available on-line

]]></description>
			<content:encoded><![CDATA[<ul>
<li><a href="http://www.washingtonpost.com/wp-srv/artsandliving/source/features/2008/beer-madness/index.html">Voting in first round of Beer Madness now open</a></li>
<li><a href="http://www.usenix.org/publications/library/proceedings/">USENIX makes old proceedings freely available on-line</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.genehack.org/2008/03/13/couple-quick-links/feed/</wfw:commentRss>
		</item>
		<item>
		<title>tab dump // 20080310</title>
		<link>http://www.genehack.org/2008/03/10/tab-dump-20080310/</link>
		<comments>http://www.genehack.org/2008/03/10/tab-dump-20080310/#comments</comments>
		<pubDate>Mon, 10 Mar 2008 10:25:05 +0000</pubDate>
		<dc:creator>genehack</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.genehack.org/2008/03/10/tab-dump-20080310/</guid>
		<description><![CDATA[
Introducing Catalyst &#8212; slides from a jrockway talk
Devel::NYTProf is the hot new profiler in town &#8212; there&#8217;s some code at work that should maybe meet this profiler
gibak &#8212; git-based backups. It&#8217;s a desert topping, it&#8217;s a floor wax&#8230;
Patch deployment via BitTorrent
We don&#8217;t understand the orbital mechanics of (relatively) small objects in hyperbolic orbits &#8212; and [...]]]></description>
			<content:encoded><![CDATA[<ul>
<li><a href="http://www.jrock.us/fp2008/catalyst/start.html">Introducing Catalyst</a> &#8212; slides from a jrockway talk</li>
<li><a href="http://perlbuzz.com/mechanix/2008/03/develnytprof-is-the-hot-new-pr.html">Devel::NYTProf is the hot new profiler in town</a> &#8212; there&#8217;s some code at work that should maybe meet this profiler</li>
<li><a href="http://eigenclass.org/hiki/gibak-backup-system-introduction">gibak</a> &#8212; git-based backups. It&#8217;s a desert topping, it&#8217;s a floor wax&#8230;</li>
<li><a href="http://arstechnica.com/news.ars/post/20080309-dropping-22tb-of-patches-on-6500-pcs-in-4-hours-bittorrentdropping-22tb-of-patches-on-6500-pcs-in-4-hours-bittorrent.html">Patch deployment via BitTorrent</a></li>
<li><a href="http://www.economist.com/science/displaystory.cfm?story_id=10804075">We don&#8217;t understand the orbital mechanics of (relatively) small objects in hyperbolic orbits</a> &#8212; and figuring out stuff we don&#8217;t understand generally leads to other cool stuff. Also, note another John Anderson who is not me.</li>
<li><a href="http://sysadminry.wordpress.com/">Down Not Across</a> &#8212; new sysadmin-ish blog</li>
<li><a href="http://materialmama.wordpress.com/2007/02/06/how-a-bobbin-works-and-some-free-pattern-ideas/">How a bobbin works</a> with animated GIF of the process. Visualizing this has always bothered me; I am soothed.</li>
<li><a href="http://blog.mwolson.org/tech/keeping_a_two-week_email_archive.html">Keeping a two-week email archive</a> - writing up the current mail flow is on the TODO
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.genehack.org/2008/03/10/tab-dump-20080310/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Sunday afternoon hacking</title>
		<link>http://www.genehack.org/2008/03/09/sunday-afternoon-hacking/</link>
		<comments>http://www.genehack.org/2008/03/09/sunday-afternoon-hacking/#comments</comments>
		<pubDate>Mon, 10 Mar 2008 02:15:20 +0000</pubDate>
		<dc:creator>genehack</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.genehack.org/2008/03/09/sunday-afternoon-hacking/</guid>
		<description><![CDATA[I&#8217;ve been using Hiveminder for several months now and I&#8217;m fairly happy with it &#8212; the task review interface in particular is a big win for me, as I can take 5 or 10 minutes in the morning and carve out a chunk of things that I can then focus on for the rest of [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using <a href="http://hiveminder.com">Hiveminder</a> for several months now and I&#8217;m fairly happy with it &#8212; the task review interface in particular is a big win for me, as I can take 5 or 10 minutes in the morning and carve out a chunk of things that I can then focus on for the rest of the day. The tag support is top notch too, so I can easily focus on work stuff at work and home stuff when not at work just by tagging things &#8216;@work&#8217; or &#8216;@home&#8217;. </p>
<p>Hiveminder provides some email tools (some with the free account, some more when you upgrade to a paid account) but they&#8217;re more oriented towards task delegation and workflow within a small group. They don&#8217;t have an interface that lets you drop a task into your list like you can when working with the web or CLI interfaces. They <em>do</em> have <a href="http://search.cpan.org/~sartak/Net-Hiveminder/lib/Net/Hiveminder.pm">an API</a>, however &#8212; so after a few hours of poking around this afternoon, I&#8217;ve written the mail gateway I&#8217;ve been wishing they had. </p>
<p>What documentation there is, including the address of the SVN repo with the code, can be found at <a href="http://trac.genehack.net/hm-mail-gateway">http://trac.genehack.net/hm-mail-gateway</a>. This isn&#8217;t a &#8220;normal&#8221; user tool; you&#8217;re going to need to modify your mail aliases, which pretty much means you need root and some understanding of how mail works. If you&#8217;re interested but don&#8217;t have that level of access on the machine where your mail lands, you could probably turn the code I have into a procmail filter without too much trouble.</p>
<p>Feedback welcome; as I said on the Hiveminder API mailing list, example code seems to be in short supply, so there&#8217;s probably a lot of ugly &#8220;make it work&#8221; stuff in my code. </p>
<p><strong>Update</strong> On the <a href="http://groups.google.com/group/hiveminder-api">Hiveminder API list</a> one of the Best Practical guys pointed out that the normal Hiveminder mail interface does let you set an &#8216;auto-accept&#8217; option. That isn&#8217;t quite the same thing as this mail gateway, but it&#8217;s pretty close, and if you don&#8217;t run your own mailserver, it&#8217;s probably the best way to get this sort of function.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.genehack.org/2008/03/09/sunday-afternoon-hacking/feed/</wfw:commentRss>
		</item>
		<item>
		<title>tab dump // 20080220</title>
		<link>http://www.genehack.org/2008/02/20/tab-dump-20080220/</link>
		<comments>http://www.genehack.org/2008/02/20/tab-dump-20080220/#comments</comments>
		<pubDate>Wed, 20 Feb 2008 11:32:28 +0000</pubDate>
		<dc:creator>genehack</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.genehack.org/2008/02/20/tab-dump-20080220/</guid>
		<description><![CDATA[
Kansas HS refuses female official &#8212; my high school used to compete against this high school. No idea they were this crazy.
Full Lunar Eclipse in the Americas tonight &#8212; supposed to be snowing here, I think
The rules of optimization club &#8212; there are several people who I would like to show rule #3 to. Need [...]]]></description>
			<content:encoded><![CDATA[<ul>
<li><a href="http://sportsillustrated.cnn.com/2008/highschool/02/13/female.official.ap/index.html?cnn=yes">Kansas HS refuses female official</a> &#8212; my high school used to compete against this high school. No idea they were this crazy.</li>
<li><a href="http://science.slashdot.org/article.pl?sid=08/02/16/1746242&#038;from=rss">Full Lunar Eclipse in the Americas tonight</a> &#8212; supposed to be snowing here, I think</li>
<li><a href="http://perlbuzz.com/mechanix/2008/02/the-rules-of-optimization-club.html">The rules of optimization club</a> &#8212; there are several people who I would like to show rule #3 to. Need to figure out a good way.</li>
<li><a href="http://www.boingboing.net/2008/02/19/goolagorg.html">cDc releases new security tool</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.genehack.org/2008/02/20/tab-dump-20080220/feed/</wfw:commentRss>
		</item>
		<item>
		<title>anonymous</title>
		<link>http://www.genehack.org/2008/02/13/anonymous/</link>
		<comments>http://www.genehack.org/2008/02/13/anonymous/#comments</comments>
		<pubDate>Wed, 13 Feb 2008 12:19:09 +0000</pubDate>
		<dc:creator>genehack</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.genehack.org/2008/02/13/anonymous/</guid>
		<description><![CDATA[First person account of anonymous CoS protest in London. Very interesting; great pics, including:

The CoS has a building in DC near Dupont Circle; was there any protest activity there?
]]></description>
			<content:encoded><![CDATA[<p><a href="http://deathboy.livejournal.com/1082404.html">First person account of anonymous CoS protest in London</a>. Very interesting; great pics, including:</p>
<p><img src="/images/oh-fuck.jpg" height="600" width="750" alt="the internet is here"/></p>
<p>The CoS has a building in DC near Dupont Circle; was there any protest activity there?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.genehack.org/2008/02/13/anonymous/feed/</wfw:commentRss>
		</item>
		<item>
		<title>tab dump // 20080213</title>
		<link>http://www.genehack.org/2008/02/13/tab-dump-20080213/</link>
		<comments>http://www.genehack.org/2008/02/13/tab-dump-20080213/#comments</comments>
		<pubDate>Wed, 13 Feb 2008 12:16:40 +0000</pubDate>
		<dc:creator>genehack</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.genehack.org/2008/02/13/tab-dump-20080213/</guid>
		<description><![CDATA[
RIP Sheldon Brown. Memorial rides April 1st?
The Great British Venn Diagram
http://cpan.org/scripts/ is a generally useful looking thing that I just found out about
Dormando&#8217;s [crappy] Operations Mantras &#8212; stuff to agree and disagree with, but thought-provoking
LISA &#8216;08 CFP
New travel document requirements for USA citizens &#8212; freedom on the march
Lego manufacturing defect rate 18 per million &#8212; [...]]]></description>
			<content:encoded><![CDATA[<ul>
<li><a href="http://sheldonbrown.com/harris/">RIP Sheldon Brown</a>. Memorial rides April 1st?</li>
<li><a href="http://qntm.org/?uk">The Great British Venn Diagram</a></li>
<li><a href="http://cpan.org/scripts/">http://cpan.org/scripts/</a> is a generally useful looking thing that I just found out about</li>
<li><a href="http://dormando.livejournal.com/484577.html">Dormando&#8217;s [crappy] Operations Mantras</a> &#8212; stuff to agree and disagree with, but thought-provoking</li>
<li><a href="http://www.usenix.org/events/lisa08/cfp/">LISA &#8216;08 CFP</a></li>
<li><a href="http://www.listbox.com/member/archive/247/2008/02/sort/time_rev/page/2/entry/7:56/20080205213358:F203F6E6-D45B-11DC-ADF3-ED678C4BADF8/">New travel document requirements for USA citizens</a> &#8212; freedom on the march</li>
<li><a href="http://www.businessweek.com/bwdaily/dnflash/content/nov2006/db20061127_153826.htm">Lego manufacturing defect rate 18 per million</a> &#8212; put that in yer &#8220;five nines&#8221; pipe and smoke it</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.genehack.org/2008/02/13/tab-dump-20080213/feed/</wfw:commentRss>
		</item>
		<item>
		<title>what i&#8217;ve been doing</title>
		<link>http://www.genehack.org/2008/01/29/what-ive-been-doing/</link>
		<comments>http://www.genehack.org/2008/01/29/what-ive-been-doing/#comments</comments>
		<pubDate>Tue, 29 Jan 2008 12:00:04 +0000</pubDate>
		<dc:creator>genehack</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.genehack.org/2008/01/29/what-ive-been-doing/</guid>
		<description><![CDATA[Or, since I haven&#8217;t made much recent progress at it, &#8220;What I&#8217;ve been trying to do while doing all the other stuff required by life&#8221;: I&#8217;m writing my own blog engine/CMS thing. I&#8217;m doing this for several reasons. First, it&#8217;s partly because I think it&#8217;s a fun thing to do and it&#8217;s a chance to [...]]]></description>
			<content:encoded><![CDATA[<p>Or, since I haven&#8217;t made much recent progress at it, &#8220;What I&#8217;ve been trying to do while doing all the other stuff required by life&#8221;: I&#8217;m writing my own blog engine/CMS thing. I&#8217;m doing this for several reasons. First, it&#8217;s partly because I think it&#8217;s a fun thing to do and it&#8217;s a chance to play around with Perl and web stuff and maybe learn a thing or two. Second, it&#8217;s partly because none of the existing tools work as well as some older tools that I can&#8217;t really use anymore, due to platform choice or rotten code. Finally, in a big way, it&#8217;s because of <a href="http://pghpw.org/ppw2007/talk/744">this talk</a> that <a href="http://www.faisal.com">Faisal Jawdat</a> gave at the 2007 Pittsburgh Perl Workshop about <a href="http://faisal.com/software/bear/">Bear</a>, which got me to realize that I can write this, and even release it, without it having to be the be-all end-all for everybody. I can do something that works for me and if others find it useful, fine; if they don&#8217;t, also fine.</p>
<p>So. It&#8217;s called <a href="http://trac.genehack.net/saguaro">Saguaro</a>. Fairly standard template-based static content generation system, using a modified Markdown and a few other things that I&#8217;ll semi-document at some point. Doesn&#8217;t all work quite right just yet, no tests to speak of, in general needs quite a bit of work, you know the drill. Lots of my discretionary time will be going towards getting this to a place where it works  well enough that I can run this site using it, at which point I&#8217;ll start porting all my old content into a form that it can deal with. If everything goes well, I&#8217;ll hopefully finish some time this year; we&#8217;ll see. There&#8217;s anonymous SVN available; holler if you want in and can&#8217;t figure out the URL. </p>
<p>See you in a couple weeks. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.genehack.org/2008/01/29/what-ive-been-doing/feed/</wfw:commentRss>
		</item>
		<item>
		<title>tab dump // 20080129</title>
		<link>http://www.genehack.org/2008/01/29/tab-dump-20080129/</link>
		<comments>http://www.genehack.org/2008/01/29/tab-dump-20080129/#comments</comments>
		<pubDate>Tue, 29 Jan 2008 11:33:42 +0000</pubDate>
		<dc:creator>genehack</dc:creator>
		
		<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://www.genehack.org/2008/01/29/tab-dump-20080129/</guid>
		<description><![CDATA[been a while.

Emergency Elisp &#8212; break glass in case, yadda yadda
Rules of Sysadmins. At $ORK, we call #8 The Friday Rule; I just wish all my cow-orkers respected it. I&#8217;d add a corrollary to rule #4: there is a better way, but you don&#8217;t have the time to implement it&#8230;
Stop the presses, Joel Spolsky writes [...]]]></description>
			<content:encoded><![CDATA[<p>been a while.</p>
<ul>
<li><a href="http://steve-yegge.blogspot.com/2008/01/emergency-elisp.html">Emergency Elisp</a> &#8212; break glass in case, yadda yadda</li>
<li><a href="http://www.ee.ryerson.ca/~elf/powerbook/#sysadminrules">Rules of Sysadmins</a>. At $ORK, we call #8 The Friday Rule; I just wish all my cow-orkers respected it. I&#8217;d add a corrollary to rule #4: there is a better way, but you don&#8217;t have the time to implement it&#8230;</li>
<li>Stop the presses, Joel Spolsky writes about system administration <em>and makes sense</em>: <a href="http://www.joelonsoftware.com/items/2008/01/22.html">Five Whys</a></li>
<li><a href="http://blag.xkcd.com/2008/01/28/obama/">xkcd endorses Obama</a>. Unrelatedly, <a href="http://www.xkcd.com/376/">yesterday&#8217;s xkcd</a> may be one of the best single-panel comics ever.</li>
<li><a href="http://www.groupnewsblog.net/2008/01/pride-and-palpitations.html">Pride and Palpitations</a> &#8212; semi-sad but very true</li>
<li><a href="http://groups.google.com/group/comp.lang.lisp/msg/f2c33661b80ba302">Rails is shitty</a></li>
<li><a href="http://metacarpal.net/blog/archives/2008/01/20/behance-dot-grid-sketchbook-beautiful-and-frustrating/">drool</a></li>
<li><a href="http://god.rubyforge.org/">God</a> &#8212; must love the tagline, &#8220;(like monit, only awesome)&#8221;</li>
<li>Words to live by: <a href="http://developer.yahoo.com/blogs/hadoop/2007/12/if_it_hurts_automate_it_1.html">If it hurts, automate it</a> (via jmason)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.genehack.org/2008/01/29/tab-dump-20080129/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Testing App::Cmd</title>
		<link>http://www.genehack.org/2008/01/09/testing-appcmd/</link>
		<comments>http://www.genehack.org/2008/01/09/testing-appcmd/#comments</comments>
		<pubDate>Wed, 09 Jan 2008 14:56:38 +0000</pubDate>
		<dc:creator>genehack</dc:creator>
		
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://www.genehack.org/2008/01/09/testing-appcmd/</guid>
		<description><![CDATA[As I mentioned last week, I&#8217;ve been working on a little reading list management tool. I&#8217;m using App::Cmd as the framework, which has been a somewhat frustrating but ultimately worthwhile choice.
I first learned of App::Cmd at the Pittsburgh Perl Workshop, through a talk given by the module&#8217;s author Ricardo Signes. The slides from that talk [...]]]></description>
			<content:encoded><![CDATA[<p>As I mentioned last week, I&#8217;ve been working on a little reading list management tool. I&#8217;m using <a href="http://search.cpan.org/~rjbs/App-Cmd-0.012/lib/App/Cmd.pm">App::Cmd</a> as the framework, which has been a somewhat frustrating but ultimately worthwhile choice.</p>
<p>I first learned of App::Cmd at the <a href="http://pghpw.org/">Pittsburgh Perl Workshop</a>, through a talk given by the module&#8217;s author Ricardo Signes. <a href="http://www.slideshare.net/rjbs/writing-modular-commandline-apps-with-appcmd/">The slides from that talk</a> are about the best App::Cmd documentation out there, although <a href="http://search.cpan.org/~rjbs/App-Cmd-0.012/lib/App/Cmd/Tutorial.pod">App::Cmd::Tutorial</a> also has some useful bits, and the module documentation itself isn&#8217;t <em>bad</em> by any means, just a little light on example code.</p>
<p>For <a href="http://trac.genehack.net/booklist">BookList</a> I didn&#8217;t do a lot of up-front design work &#8212; I was basically designing as I went and learning App::Cmd at the same time. As a result, I ended up implementing several commands with only the most rudimentary tests &#8212; basically, if the command module loaded, I was happy. Since BookList is getting towards a 0.1 level of functionality and I&#8217;d like to release it, I spent the past couple days renewing my appreciation of &#8220;test first&#8221; development by going back and writing all the tests I skipped over the first time through.</p>
<p>Because of the way the framework works, testing App::Cmd code is a bit different than testing library-level routines. The talk I pointed to above has a section on testing (around slide 115, for those of you who want to check it out), which references a nifty looking module called Test::App::Cmd. Unfortunately, the module doesn&#8217;t appear to be publicly available yet. (This might have been mentioned at the talk; I don&#8217;t recall. Any status updates are welcomed.)</p>
<p>After poking around on CPAN, trying to find something to provide some scaffolding for my tests, I ended up finding a module called <a href="http://search.cpan.org/~ssoriche/Test-Output-0.10/lib/Test/Output.pm">Test::Output</a>. I used that and the sample test code in the talk to write a bunch of tests that looked like this:</p>
<pre><code>
use Test::More     qw/ no_plan /;
use Test::Output   qw/ stdout_from /;

use Booklist::Cmd;

my $error;
my $stdout = do {
  local @ARGV = ( 'authors' );
  stdout_from( sub {
    eval { Booklist::Cmd->run ; 1 } or $error = $@;
  } );
};

like $stdout , qr/^###  #bk  author/ , 'see expected header';
ok ! $error;
</code></pre>
<p>and while that mostly worked out okay, I ran into trouble with some of my error-handling code. When writing libraries, especially for my personal use, I tend towards the low-budget &#8220;croak() and let the caller deal&#8221; method of exception handling. But for something that&#8217;s going to be more application-level, I wanted to print messages to STDERR and then exit() with a non-zero status. This doesn&#8217;t play well with <a href="http://search.cpan.org/~mschwern/Test-Simple-0.74/lib/Test/More.pm">Test::More</a> or Test::Output, neither of which trap calls to exit().</p>
<p>After a bit more <a href="http://search.cpan.org/">CPAN searching</a>, I found <a href="http://search.cpan.org/~ebhanssen/Test-Trap-v0.0.23/lib/Test/Trap.pm">Test::Trap</a> which is <em>excellent</em> for testing App::Cmd code. The above code rewritten to use Test::Trap looks like this:</p>
<pre><code>
use Test::More    qw/ no_plan /;
use Test::Trap    qw/ trap $trap /;

use Booklist::Cmd;

trap {
  local @ARGV = ( 'authors' );
  Booklist::Cmd->run;
};

$trap->leaveby_is( 'return' , 'exit normally' );
$trap->stdout_like( qr/^###  #bk  author/ , 'see expected header' );
$trap->stderr_nok( 'nothing on stderr' );
</code></pre>
<p>That second code block is a lot cleaner and easier to understand than the first one (not to mention being fewer LOC while doing an additional test), and the accessor/comparison methods (leaveby_is, stdout_like, etc.) from Test::Trap are both easy to write and (if you know anything at all about idiomatic Perl testing code) trivial to understand.</p>
<p>I&#8217;m going back now and rewriting all my previous Test::Output tests to use Test::Trap &#8212; but I&#8217;ve also learned another lesson here: my last test is currently failing, because I wrote it <em>before</em>implementing the command it tests.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.genehack.org/2008/01/09/testing-appcmd/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
