<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" version="2.0">
    <channel>
        <title>Mechanix</title>
        <link>http://perlbuzz.com/mechanix/</link>
        <description>Code, tech and getting dirt under your fingernails</description>
        <language>en</language>
        <copyright>Copyright 2008</copyright>
        <lastBuildDate>Mon, 02 Jun 2008 23:09:58 -0600</lastBuildDate>
        <generator>http://www.sixapart.com/movabletype/</generator>
        <docs>http://www.rssboard.org/rss-specification</docs>
        
        <geo:lat>42.348406</geo:lat><geo:long>-88.247697</geo:long><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/PerlBuzzMechanix" type="application/rss+xml" /><item>
            <title>Scrabble cheating with Perl one-liners</title>
            <description><![CDATA[<p>
I'm in the middle of a game of Scrabulous with <a href="http://niroze.net/">Christoper Humphries</a> on Facebook, and I get "tolkien" handed to me in my tray.  Good letters, and I ought to be able to make a bingo out of them.  Alas, the best I could get to play on the board was "knot", but what else could I have made?  Perl to the rescue!
</p>
<p>
All I need to do is match across the contents of /usr/share/dict/words in a Perl one-liner.  The <tt>-n</tt> flag means "loop over the input file, but don't print $_".  My little program goes in <tt>-e</tt>, and it looks like this:
</p>
<pre>
$ perl -lne'print if /t/ && /o/ && /l/ && /k/ && /i/ &&
    /e/ && /n/' /usr/share/dict/words 
allokinetic
ankylopoietic
anticlockwise
automatonlike
bibliokleptomania
....
</pre>
<p>
Lots of good words, but they're awfully long.  Let's limit it to seven-letter bingos.  We have to use the <tt>-l</tt> flag to drop the linefeed from the input lines, so the <tt>length</tt> call is accurate.
</p>
<pre>
$ perl -lne'print if /t/ && /o/ && /l/ && /k/ && /i/ &&
    /e/ && /n/ && length($_)==7' /usr/share/dict/words
$
</pre>
<p>
Shoot, nothing there.  Let's try eight.
</p>
<pre>
perl -lne'print if /t/ && /o/ && /l/ && /k/ && /i/ &&
    /e/ && /n/ && length($_)==8' /usr/share/dict/words 
knotlike
townlike
</pre>
<p>
"knotlike"!  That would have been beautiful.  Oh well. :-(
</p>]]></description>
            <link>http://perlbuzz.com/mechanix/2008/06/scrabble-cheating-with-perl-on.html</link>
            <guid>http://perlbuzz.com/mechanix/2008/06/scrabble-cheating-with-perl-on.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Code craft</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Data munging</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Scrabble</category>
            
            <pubDate>Mon, 02 Jun 2008 23:09:58 -0600</pubDate>
        </item>
        
        <item>
            <title>Use Getopt::Long even if you don't think you need to</title>
            <description><![CDATA[<p>
<a href="http://perlmonks.org/?node_id=687283">Thread over on perlmonks</a> talks about Tom Christiansen's assertion that you should use it, by default, even when you only have one command-line argument to parse:
</p>
<blockquote>
    What seems to happen is that at first we just want to add--oh say for example JUST ONE, SINGLE LITTLE -v flag. Well, that's so easy enough to hand-hack, that of course we do so... But just like any other piece of software, these things all seem to have a way of overgrowing their original expectations... Getopt::Long is just *wonderful*, up--I believe--to any job you can come up with for it. Too often <b>its absence means that I've in the long run made more work for myself--or others--by not having used it originally.</b> [Emphasis mine -- Andy]
</blockquote>
<p>
I can't agree more.  I don't care if you use
<a href="http://search.cpan.org/dist/Getopt-Long">Getopt::Long</a> or
<a href="http://search.cpan.org/dist/Getopt-Declare">Getopt::Declare</a> or
<a href="http://search.cpan.org/dist/Getopt-Lucid">Getopt::Lucid</a> or any of the other
<a href="http://search.cpan.org/search?query=getopt&mode=dist">variants out there</a>.  You know <i>know</i> <b>know</b> that you're going to add more arguments down the road, so why not start out right?
</p>
<p>
Yes, it can be tricky to get through all of its magic if you're unfamiliar with it, but it's pretty obvious when you see enough examples.  Take a look at <i>prove</i> or <a href="http://petdance.com/ack/"><i>ack</i></a> for examples.  <a href="http://search.cpan.org/src/PETDANCE/WWW-Mechanize-1.34/bin/mech-dump">mech-dump</a> is pretty decent as an example as well:
</p>
<pre>
GetOptions(
    'user=s'        => \$user,
    'password=s'    => \$pass,
    forms           => sub { push( @actions, \&dump_forms ); },
    links           => sub { push( @actions, \&dump_links ); },
    images          => sub { push( @actions, \&dump_images ); },
    all             => sub { push( @actions, \&dump_forms, \&dump_links, \&dump_images ); },
    absolute        => \$absolute,
    'agent=s'       => \$agent,
    'agent-alias=s' => \$agent_alias,
    help            => sub { pod2usage(1); },
) or pod2usage(2);
</pre>
<p>Where the value in the hashref is a variable reference, the value gets stored in there.  Where it's a <tt>sub</tt>, that sub gets executed with the arguments passed in.  That's the basics, and you don't have to worry about anything else.  Your user can pass --abs instead of --absolute if it's unambiguous.  You can have mandatory flags, as in agent=s, where --agent must take a string.  On and on, it's probably got the functionality you need.
</p>
<p>
One crucial reminder: You <b>must</b> check the return code of <tt>GetOptions</tt>.  Otherwise, your program will carry on. If someone gives your program an invalid argument on the command-line, then you <b>know</b> that the program cannot possibly be running in the way the user intended.  Your program must stop immediately.
</p>
<p> Not checking the return of <tt>GetOptions</tt> is as bad as not checking the return of <tt>open</tt>.  In fact, I think I smell a new <a href="http://perlcritic.tigris.org/">Perl Critic</a> policy....</p>
]]></description>
            <link>http://perlbuzz.com/mechanix/2008/05/use-getoptlong-even-if-you-don.html</link>
            <guid>http://perlbuzz.com/mechanix/2008/05/use-getoptlong-even-if-you-don.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Code craft</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Modules</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Tools</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Getopt::Long</category>
            
            <pubDate>Sun, 25 May 2008 21:20:17 -0600</pubDate>
        </item>
        
        <item>
            <title>Pragmatic Programmer on estimating</title>
            <description><![CDATA[<p>
From <a href="http://www.pragprog.com/the-pragmatic-programmer/extracts/tips">The Pragmatic Programmer</a>:

<BLOCKQUOTE>
What's the value of <I>pi</I>?  If you're wondering how much edging to
put around a circular flower bed, then "3" is probably good enough.
If you're in school, then maybe "22/7" is a good approximation.  If
you're in NASA, then maybe 12 decimal places will do.
</BLOCKQUOTE>
]]></description>
            <link>http://perlbuzz.com/mechanix/2008/05/pragmatic-programmer-on-estima.html</link>
            <guid>http://perlbuzz.com/mechanix/2008/05/pragmatic-programmer-on-estima.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Code craft</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">estimating</category>
            
            <pubDate>Sat, 17 May 2008 23:58:02 -0600</pubDate>
        </item>
        
        <item>
            <title>How to write a simple database-backed website with Perl modules Mason and Class::DBI</title>
            <description><![CDATA[<p>
<a href="http://search.cpan.org/~alfie/">Alfie John</a> over at <a href="http://rental-property.co.nz">rental-property.co.nz</a> wrote to tell that the source code for the entire site, written using <a href="http://www.masonhq.com/">Mason</a> and <a href="http://wiki.class-dbi.com/wiki/Main_Page">Class::DBI</a>, is <a href="http://rental-property.co.nz/source/">available for download</a>.
</p>
<p>
For someone wanting to see an overview of how either Mason or Class::DBI work with real-world examples, not just samples from documentation, this is a great place to start.
</p>]]></description>
            <link>http://perlbuzz.com/mechanix/2008/05/how-to-write-a-simple-database.html</link>
            <guid>http://perlbuzz.com/mechanix/2008/05/how-to-write-a-simple-database.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Databases</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Web</category>
            
            
            <pubDate>Fri, 16 May 2008 23:48:24 -0600</pubDate>
        </item>
        
        <item>
            <title>Optimizing file searches with File::Find::Rule</title>
            <description><![CDATA[<p>
Adam Kennedy posted an excellent article about <a href="http://use.perl.org/~Alias/journal/36415">huge performance hits he found with File::Find::Rule</a>.  From the docs, there's this sample to find all the *.pm files in <tt>@INC</tt>:
</p>
<blockquote>
<pre>
# Find all the .pm files in @INC
my @files = File::Find::Rule->file
                            ->name( '*.pm' )
                            ->in( @INC );
</pre>

<p>
What this search REALLY says is "Find every single file in all these trees, then do an slow IO stat call to the operating system on every single one to work out which ones are files, and only then do a quick regex match on the file names to keep the 5% that have the ending we want and throw away the 95% that don't".
</p>
</blockquote>
<p>
Now I'm worried about if I'm doing the right order of checking in <a href="http://search.cpan.org/dist/File-Next/">File::Next</a>, a lightweight file finder that <a href="http://petdance.com/ack/">ack</a> relies on.
</p>]]></description>
            <link>http://perlbuzz.com/mechanix/2008/05/optimizing-file-searches-with.html</link>
            <guid>http://perlbuzz.com/mechanix/2008/05/optimizing-file-searches-with.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">CPAN</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">ack</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">File::Find::Rule</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">File::Next</category>
            
            <pubDate>Wed, 14 May 2008 09:07:07 -0600</pubDate>
        </item>
        
        <item>
            <title>The case of the blocking CREATE INDEX call</title>
            <description><![CDATA[<p>
I'd been working on a new functional index for the <a href="http://titletales.com/">work website</a>.  I created a Pgsql function to normalize the title of a book
</p>
<pre>
CREATE OR REPLACE FUNCTION exacttitle_key( TEXT ) 
    RETURNS text AS $$
    DECLARE
        key TEXT := upper( $1 );

    BEGIN
        key = regexp_replace( key,
            '^ *(?:A|AN|EL|LA|LO|THE|LOS|LAS)\\M *', '' );
        key = regexp_replace( key, '[^0-9A-Z ]+', '', 'g' );
        key = regexp_replace( key, ' {2,}', ' ', 'g' );

        RETURN trim( key );
    END

$$ LANGUAGE 'plpgsql'
IMMUTABLE STRICT;
</pre>
<p>
and tested it out, and all looked well.  It was marked as IMMUTABLE, so Pg can use it as an index function.  I created the index in psql:
</p>
<pre>
create index testbook_exacttitle on testbook 
    using btree (exacttitle_key(title));
</pre>
<p>
And all was well.  Now I wanted to see how long it took to create that index, so from the shell I did:
</p>
<pre>
$ time psql -c'drop index testbook_exacttitle; \
    create index testbook_exacttitle  on testbook \
    using btree (exacttitle_key(title));'
</pre>
<p>
I knew it would take about 5 minutes to add this index on 6.7 million records in testbook, so I didn't expect it to come back right away.  Then I realized that site response fell off the table.  <a href="http://ptop.projects.postgresql.org/">ptop</a> showed a couple dozen SELECT queries waiting to run.  I killed the process that was running the CREATE INDEX.  All the pending queries went on their merry way.  Everything was back to normal.
</p>
<p>
I tried that command line again, and the results were identical.  Dozens of queries backed up until I killed the CREATE INDEX process.  But why were those queries backing up?  That index was not used by any code yet.  I asked in #postgresql, but nobody knew the answer.  Then, someone said a word that clicked in my head.  I made a little change to how I was running the commands, and everything worked just fine.
</p>
<p>
<b><i>What was the word that helped Encyclopedia Lester figure out the problem?</i></b>  Turn to page 47 for the answer.
</p>
<p>
The word was "transaction".  If there are multiple commands as part of the -c option to <i>psql</i>, they are executed in in one transaction.  DROP INDEX blocks on the entire table, so the entire transaction blocked.  When I ran the DROP INDEX separately, and then reran the CREATE INDEX by itself, there was only the long blocking on the new index, which did not yet exist.
</p>
<p>
(With apologies to Donald J. Sobol and <a href="http://en.wikipedia.org/wiki/Encyclopedia_Brown">Encyclopedia Brown</a>)
</p>]]></description>
            <link>http://perlbuzz.com/mechanix/2008/04/how-to-accidentally-lock-up-yo.html</link>
            <guid>http://perlbuzz.com/mechanix/2008/04/how-to-accidentally-lock-up-yo.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Databases</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">PostgreSQL</category>
            
            <pubDate>Tue, 29 Apr 2008 09:22:12 -0600</pubDate>
        </item>
        
        <item>
            <title>What commands do you run?</title>
            <description><![CDATA[<p>
<a href="http://textism.com/2008/04/16/no.one.tagged.me">People have been posting</a> in their blogs about what command they run, based on their shell histories.  The command that I've seen looks like this:
</p>
<pre>
history|awk '{a[$2]++} END{for(i in a){ \
printf "%5d\t%s \n",a[i],i}}'|sort -rn|head
</pre>
<p>
That works, of course, but who wants to use awk and the shell?  I pulled out the old Data::Hash::Totals module I wrote a while back, along with Perl's built-in awk simulation:
</p>
<pre>
$ history | perl -MData::Hash::Totals -ane'$x{$F[1]}++;' \
-e'END{print as_table(\%x, comma => 1)}' | head
207 vim
143 svn
125 make
 90 ack
 77 cd
 45 sdvx
 34 ssq
 31 ls
 25 ./login-fixup
 19 tail

alester:~ : cat `which sdvx`
#!/bin/sh

svn diff -x -w $* | view -
</pre>

and <tt>ssq</tt> is just an alias for <tt>svn status -q</tt>.
]]></description>
            <link>http://perlbuzz.com/mechanix/2008/04/what-commands-do-you-run.html</link>
            <guid>http://perlbuzz.com/mechanix/2008/04/what-commands-do-you-run.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Tools</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Awk</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">shell</category>
            
            <pubDate>Wed, 16 Apr 2008 10:31:38 -0600</pubDate>
        </item>
        
        <item>
            <title>Google now returns code snippets</title>
            <description><![CDATA[<p>
Google's main search screen now returns code snippets in its list of results.  This is not just in code.google.com any more.
</p>

<P>
 I needed to find the docs for the PHP function <tt>ftp_connect</tt>, so searched Google for it.  (I could have gone to <a href="http://www.php.net/">php.net</a> and searched there, but why?)
<a href="http://www.google.com/search?q=ftp_connect">The list of results</a> has three hits to PHP manual pages, and the fourth and fifth are bits of code that use <tt>ftp_connect</tt>.  Anyone know if they're getting Perl stuff in there as well?  I tried it with WWW::Mechanize, but couldn't turn up hits.</p>]]></description>
            <link>http://perlbuzz.com/mechanix/2008/03/google-now-returns-code-snippe.html</link>
            <guid>http://perlbuzz.com/mechanix/2008/03/google-now-returns-code-snippe.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Documentation</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Web</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Google</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">PHP</category>
            
            <pubDate>Mon, 31 Mar 2008 13:14:06 -0600</pubDate>
        </item>
        
        <item>
            <title>Technical debt in your file headers</title>
            <description><![CDATA[<p>
Here's a little <a href="http://beautifulcode.oreillynet.com/2008/03/the_file_header_tax.php">article about the "file header tax"</a>, lines of boilerplate at the top of files that serve no purpose.  Copyright notices, disclaimers, maybe even some revision history, it's all just clutter, and clutter is technical debt.
</p>
<p>
Take a look at the next file you edit.  Is there anything at the top of it that is not functional code?  Ask yourself if it <i>really</i> needs to be there.  If in doubt, throw it out.
</p>]]></description>
            <link>http://perlbuzz.com/mechanix/2008/03/technical-debt-in-your-file-he.html</link>
            <guid>http://perlbuzz.com/mechanix/2008/03/technical-debt-in-your-file-he.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Code craft</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">technical debt</category>
            
            <pubDate>Wed, 26 Mar 2008 12:26:21 -0600</pubDate>
        </item>
        
        <item>
            <title>Don't use Plucene for real work</title>
            <description><![CDATA[<p>
Just in case anyone's using Plucene as a search engine, please don't.  It's terribly slow.  Take a look at KinoSearch instead.  Plucene is written in pure Perl, mostly as a proof of concept.  It is literally orders of magnitude slower than KinoSearch, which uses C for the hard bits.  Here's a <a href="http://www.kinosearch.com/kinosearch/benchmarks.html">page of benchmarks</a> to make the point.
</p>]]></description>
            <link>http://perlbuzz.com/mechanix/2008/03/dont-use-plucene-for-real-work.html</link>
            <guid>http://perlbuzz.com/mechanix/2008/03/dont-use-plucene-for-real-work.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Tools</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">KinoSearch</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">Plucene</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">search engines</category>
            
            <pubDate>Tue, 25 Mar 2008 13:08:18 -0600</pubDate>
        </item>
        
        <item>
            <title>Don't trust yourself or your code</title>
            <description><![CDATA[<p>
Jared Parsons writes about how
<a href="http://blogs.msdn.com/jaredpar/archive/2008/03/24/part-of-being-a-good-programmer-is-learning-not-to-trust-yourself.aspx">Part of being a good programmer is learning not to trust yourself</a>.  It's filled with basic but all-too-often-forgotten wisdom about defensive programming.  Key bits:  "Turn assumptions into compiler errors," "The best way to avoid making bad assumptions is to actively question them at all times," and "1 test is worth 1000 expert opinions."
</p>
<p>
I also chuckled to see a sidebar disclaimer that said "All code posted to this site is covered under the Microsoft Permissive Lice."  I'd heard of parasitic licensing before, but never like this!
</p>]]></description>
            <link>http://perlbuzz.com/mechanix/2008/03/dont-trust-yourself-or-your-co.html</link>
            <guid>http://perlbuzz.com/mechanix/2008/03/dont-trust-yourself-or-your-co.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Code craft</category>
            
                <category domain="http://www.sixapart.com/ns/types#category">Programmers</category>
            
            
            <pubDate>Mon, 24 Mar 2008 13:57:05 -0600</pubDate>
        </item>
        
        <item>
            <title>ack 1.78 is out</title>
            <description><![CDATA[<p>
After three months of lots of development work and intermediate releases, I've released <a href="http://petdance.com/ack/">ack 1.78</a>.  There are tons of new features and lots of compatibility fixes for Windows.  ack is a replacement for grep that is geared to working with trees of code.
</p>
<p>
Highlights in this release include:
<ul>
<li>Files specified on the command line are always searched, even if they don't match a known filetype</li>
<li>Ability to ignore directories</li>
<li>Pager support</li>
<li>More flexible grouping options</li>
<li>Many more languages recognized and existing ones improved, including CFMX, Actionscript, assembly, Tcl, Lisp, Smalltalk
<li>Ability to define your own languages based on filetype</li>
</ul>
<p>
ack may well change the way you work on the command-line with source code.  Try it out and let me know what you think.  You can install it by installing App::Ack from CPAN, or downloading the standalone version to your ~/bin directory.
</p>]]></description>
            <link>http://perlbuzz.com/mechanix/2008/03/ack-178-is-out.html</link>
            <guid>http://perlbuzz.com/mechanix/2008/03/ack-178-is-out.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Tools</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">ack</category>
            
            <pubDate>Mon, 24 Mar 2008 01:29:02 -0600</pubDate>
        </item>
        
        <item>
            <title>Use seq or jot to do repetitive numbering</title>
            <description><![CDATA[<p>
I just now had to clean up some tables in a PostgreSQL database.  The prior DBA thought that it would be good to split up tables into lx1, lx2, lx3 up to lx20.  After I combined all the tables together, I needed to drop the originals.  I could have written a Perl program to generate a series of <tt>drop table lx1;</tt> commands to feed into the <tt>psql</tt> command-line client, but instead I used the <tt>seq</tt> tool:
</p>
<pre>
$ seq -f'drop table lx%g;' 1 20
drop table lx1;
drop table lx2;
...
drop table lx20;
</pre>
<p>
If you don't have <tt>seq</tt> on your system, as on Mac OS X, you probably have <tt>jot</tt>, as in:
</p>

<pre>
jot -w'drop table lx%g;' 20 1
</pre>

<p>
Then again, if you just <i>have</i> to do it in Perl:
</p>
<pre>
perl -le'print qq{drop table lx$_;} for 1..20'
</pre>
<p>
but I like to use other tools than the Swiss Army Chainsaw sometimes.
</p>]]></description>
            <link>http://perlbuzz.com/mechanix/2008/03/use-seq-or-jot-to-do-repetitiv.html</link>
            <guid>http://perlbuzz.com/mechanix/2008/03/use-seq-or-jot-to-do-repetitiv.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Tools</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">jot</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">seq</category>
            
            <pubDate>Sat, 08 Mar 2008 17:01:36 -0600</pubDate>
        </item>
        
        <item>
            <title>Devel::NYTProf is the hot new profiler in town</title>
            <description><![CDATA[<p>
Adam Kaplan has released a cool new profiling tool, <a href="http://search.cpan.org/dist/Devel-NYTProf/">Devel::NYTProf</a>.  It's apparently taken the formatting beauty of <a href="http://search.cpan.org/dist/Devel-Coverf/">Devel::Cover</a>, the code test coverage tool, and used it to identify hotspots in your code.  The results are beautiful: <a href="http://graphics8.nytimes.com/images/blogs/open/05screenshotindex.png">Overview</a> and <a href="http://graphics8.nytimes.com/images/blogs/open/05screenshotprofile.png">module-level detail</a>.  There's also a report writer that provides CSV output and lets you create your own output in your own format.
</p>
<p>
I ran into a divide-by-zero error that I patched in my local copy, but other than that the results seem good.  I look forward to whatever other improvements come.  I'm also glad it's been <a href="http://perlbuzz.com/2008/03/more-companies-openly-supporting-perl-projects.html">released with the support of the New York Times</a>.
</p>]]></description>
            <link>http://perlbuzz.com/mechanix/2008/03/develnytprof-is-the-hot-new-pr.html</link>
            <guid>http://perlbuzz.com/mechanix/2008/03/develnytprof-is-the-hot-new-pr.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Tools</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Adam Kaplan</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">Devel::Cover</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">Devel::NYTProf</category>
            
            <pubDate>Wed, 05 Mar 2008 22:45:40 -0600</pubDate>
        </item>
        
        <item>
            <title>The worst way to shorten names</title>
            <description><![CDATA[<p>
Dropping vowels to shorten names is a terrible practice.  Quick, someone give me an idea what <tt>$hdnchgdsp</tt> means, an Actual Variable from some Bad Code I'm working on today.
</p>
<p>
It's not just variables names, either.  Filenames often need to be shortened, but dropping vowels is not the way to do it.  You're left with unpronounceable names that are annoying to type.
</p>
<p>
The key to effective abbreviation is not removal of letters from the middle of the words, but from the end.  Sometimes, it doesn't make sense to shorten a word at all, like "post". If you have a file that is supposed to "post audit transactions", call it "post-aud-trans" or "post-aud-trx", not "pst_adt_trns".
</p>]]></description>
            <link>http://perlbuzz.com/mechanix/2008/03/the-worst-way-to-shorten-names.html</link>
            <guid>http://perlbuzz.com/mechanix/2008/03/the-worst-way-to-shorten-names.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">Code craft</category>
            
            
            <pubDate>Wed, 05 Mar 2008 09:33:23 -0600</pubDate>
        </item>
        
    </channel>
</rss>
