|Perl Monk, Perl Meditation|
Reactionary Coding—One-Shot Programsby John M. Dlugosz (Monsignor)
|on Jun 13, 2001 at 22:36 UTC||Need Help??|
Yesterday I was asked if I knew of a tool to do something that was a lot of work to do by hand (arranging a huge number of files onto several properly-sized CD images to offload them). I said, “Easy enough to do in Perl.” and helped him through it.
However, as a software engineer I normally think about robust solutions and self-contained shipping products. Furthermore, Perl has evolved toward programming in the large, and those are the techniques I normally use.
So, this Meditation is about what I noticed in breaking with that tendency, and how writing a special-purpose program that will run once is fundimentally different. This is becoming more forign to us as software becomes more of an engineering discipline.
I call this Reactionary as a double entendre: it is a reaction (solution) to a specific problem, and is seeking to undo our revolutions in techniques.
So, the first thing I noticed concerned the need to iterate over all the filenames in the source directory tree. Do I teach him to use File::Find or otherwise write some other sub to do that, and take command-line arguments to specify the starting directory and options? No! I generated the list using dir /fsb on my 4DOS/NT Shell and gave him the list. He doesn't have that shell, but he can use this file of fully-quallified file names as input with the magical <> operator.
That's what got me thinking that this is different from normal programming. Programs tend to become more complex with time, so we try to make it general in the first place, with an overall architecture that can handle unexpected changes. Not providing a way to change my input parameter is quite contrary to that!
Likewise, robustness is the next thing to go out the window. Make sure the destination directory exists? Who cares—if it doesn't work I'll run it again, and once it runs once, I don't need it anymore.
However, my friend caught me thinking large on another step. Changing the source name to the dest name, I was going to pull out the proper File:: module to break it into parts, and figure out the relative path of interest. He reminded me that we know the source path as a constant in the program! A simple s/// to change the first part of the name is sufficient. In a “real” program this would give me the willies. But for solving a specific problem, it's simple and correct and hard to get wrong and won't need debugging.
So, I was reminded through this exersize that I don't always have to write reusable, robust, code. Sometimes a brittle highly specific solution is better, and there is a lot of mentality to overcome in order to write in that style.
But, I still use strict and so on. Hard-coding things and assuming things about the run is not the same as writing a golf-ish one-liner. They are different concepts, and can be applied independantly. Code well, just allow assumptions about the specific run to afect your code.