There's always a better way...

I work in a lot of languages, and I feel like I’m productive in just about all of them…I mean I usually get my problems solved and things (eventually) work. I guess it’s one of the reasons I’m able to pay the bills by coding. But still, as active and productive as I might appear, I’m more of a utility programmer than I am a master. I can work in lots of languages, and I can come up with lots of angles and solutions…but they still aren’t always the ‘best’ answers. This was the case for a recent Perl program I dumped on this blog. It worked and it solved my problem well enough at the time - which goes along with my overall coding philosophy (1. Make it work, 2. Make it fast (if you have time), 3. Make it good (if you have interest)) Anyway sharing my quick hack on this blog gave a better programmer - Donnie Cameron - the chance to improve upon it (which by the way is just another awesome side advantage to sharing this type of thing via a blog). Because his improvements really do make the program a lot better, I asked him if I could republish his email (and as you can see he graciously agreed!):

The program is very neat because, despite its tiny size, it communicates with the disk, with a web service, and with a database. I couldn’t help thinking of some minor modifications. I’ve written a new program that looks very much like your own, but that includes things that I would have done differently. The only reason I’m providing this program to you is because I’m tired and I am no longer able to focus on my real work today. Please forgive me. I don’t have access to the tables and the database that you’re using, so I didn’t test this program. But I’m confident it would work without modification (aside from the changing the username, password, and other settings, of course). There are a few noteworthy pros for the new program. * Roughly 25 lines long, compared to the 40+ lines in the original. (This is after excluding comments and blank lines from both.) * Every line in the new program is less than 75 characters wide, which allows for easy reading, printing, publishing, exchanging, and diffing. * Faster because of how it slurps files, how it prepares and executes SQL statements, how it reduces instantiation of objects, and how it requests one less module. * More secure because of how it prepares and executes SQL statements. * Measurably easier to debug. But there are cons * The program might be more difficult to read for people that haven’t used Perl extensively * Requires more comments, uses Perlisms
use DBI; use LWP::UserAgent; use warnings; use strict; # I never use temporary values unless I really have to my $dbh= DBI->connect('dbi:Oracle:my_db’, 'username’, 'password’); # Preparing a statement once, with a placeholder, is faster and safer # than assembling SQL and preparing the statement in each iteration of # a loop. my $sth= $dbh->prepare(   "select count(1) from my_sdl_storage_table where xml like ?“) or die; # Better to instantiate this once only my $ua= LWP::UserAgent->new; # Declare a few variables and define the first one my ($reccount, $filename, $xml, $isbn, $response)= 0; foreach $filename ( </local-file-path/isbnmemberwebservice*> ) {   $reccount++;   # Fastest way to slurp the contents of a file   $xml= do { local(@ARGV, $/)= $filename; <> };   # We won’t do anything else with this file if it doesn’t have an ISBN 13   next unless $xml =~ /<isbn13>(\d+)<\/isbn13>/s;   $isbn= $1;   # Provide a value for the placeholder and execute the statement   $sth->execute(’%<isbn13>’ . $isbn . ’</isbn13>%’) or die;   # Post to the Web service when the database doesn’t contain the ISBN   if($sth->fetchrow_array) {     $response= $ua->post("http://webservice”, [xml => $xml]);     die $response->status_line unless $response->is_success;     print “$reccount: $isbn record updated in MY_SDL_STORAGE_TABLE\n”;   } else {     print “$reccount: $isbn NO RECORD\n”;   } }
Note: In case you can’t tell, Donnie is a pretty high level programmer - especially when it comes to Perl (but he’s rock solid in many other languages and concepts as well). As a master he often uses a style/format that can be a bit harder for lesser programers to quickly read through (I’m refering to things like spaces and line breaks)…I took the liberty of reformatting his solution into what I considered a more reader-friendly style before I shared it with you. Everything he points out above are very good points, and things that I *should* have thought of when I was hacking the program togther…in fact most are things I like to *think* I would have thought of had I needed to spend more time with this problem (though in reality some like the different file parsing bits aren’t things I probably would have thought much about). Still it’s clear that bouncing from language to language so often like I do can often affect how you approach problems and implement solutions - and not always in an ideal way. Lucikly, I have some SUPER smart friends who can come in and fix my mess up from time to time and keep me thinking about the right path to the master level!

This post has received 45 loves.


ARCHIVE OF POSTS



This is the personal blog of Kevin Marshall (a.k.a Falicon) where he often digs into side projects he's working on for digdownlabs.com and other random thoughts he's got on his mind.

Kevin has a day job as CTO of Veritonic and is spending nights & weekends hacking on Share Game Tape. You can also check out some of his open source code on GitHub or connect with him on Twitter @falicon or via email at kevin at falicon.com.

If you have comments, thoughts, or want to respond to something you see here I would encourage you to respond via a post on your own blog (and then let me know about the link via one of the routes mentioned above).