One of the things that made me into a Perl enthusiast was the language's ability to express a complex thought on a single line. I've found myself golfing down some algorithms to fewer lines until I end up with odd and arcane looking lines such as:

else { last if !defined (($_ = <>) =~ s!\n|$/!!g); }

...which reads a chunk of ARGV into $_, removes newlines, chomps, and should exit the loop it is a part of at the end of the last ARGV file, or on any chunk not containing a newline or input record separator. Or better yet:

@{$temp_hash{files}} = grep { /@(\d+)$/; $1 > $old } @{$temp_hash{ +files}};

...which is a filter to keep only those elements of an array (that is part of a hash) where the digits following an @ sign next to the end of the line are greater than the scalar $old.

Sometimes lines like that look odd or clumsy. Other times they look elegant and I'm proud of them. They are always difficult to squeeze through a code review, and most times I'll leave their more explicit and easier-to-read cousins in place in an initial release, and show the new code and some tests showing that it works the same as the original at a later time.

It doesn't always seem worth the effort, so I'm hesitant to try to improve my co-workers' "code eyes" (for lack of a better term), and leave the easier to read versions in place, since, after all, the two versions do the same thing. Also, the comments that I litter my production code with tend to express what is going on at a lower level, inflating the size of a simple project until it looks like it was more of a challenge than it really was.

My new challenge, then, is to cultivate the middle ground. Coding for clarity, seeking to stay below the critical mass that clouds over the eyes of my fellows at code review time, while still maintaining as much of my arbitrary elegance as possible. After a few attempts in that direction, I started ending up with code that has an interesting flavor, such as this home-grown CSV splitter:

sub csv_split { local $_ = shift || return undef; my @array = (); my $count = my $quoted = 0; while ( s/(.)// ) { if ($1 eq ',' && !$quoted) { $count++; next; } if ($1 eq q/"/) { unless ( $quoted && s/^\"// ) { $quoted = 1 - $quoted; nex +t; } } $array[$count] .= $1; } @array; }

It's not hard to squeeze something like that through a review. The "while" line, for example, is easy to explain, and so is the fact that that the s/^\"// won't adversely effect $1 since a match means we don't care about $1 any more. The code keeps a nice feel without losing much conciseness or readability, and to boot I'm able to come back to it at a later date and see what my intentions were. In my earlier examples, revisiting the scripts a couple weeks later invokes an initial head scratching reaction, and sometimes a shock of thinking I miscoded the whole thing until I've got it all sorted out again.

If I were to start publishing some modules on CPAN for public consumption, this is the style I think I would stick with. It doesn't look like I'm trying to belittle the intended audience with my aristocratic airs, and it gets the point across pretty cleanly.

Update: Added readmore tag.


In reply to Code for elegance, code for clarity by delirium

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.