The Logic of Programs

Ovid on 2007-08-20T21:37:22

A program, to my mind, is basically code which does something. A module or class on its own doesn't do anything. It's not a program. You need a program to use them and do something. However, the problem which I see all too often is programs which try to do too much. As a result, when I wrote grepl, I did not want any logic in there which belong in the App::Grepl class. Though grepl is powerful and does a lot, here's the entire program:

#!/usr/local/bin/perl

use strict;
use warnings;
use App::Grepl;
use Pod::Usage 1.12;

use Getopt::Long;
GetOptions(
    "pattern=s" => \my $pattern,
    "search=s"  => \my $lookfor,
    "warnings"  => \my $warnings,
    "l"         => \my $filename_only,
    'h|help|?'  => sub { pod2usage( { -verbose => 1 } ); exit },
    'H|man'     => sub { pod2usage( { -verbose => 2 } ); exit },
);

$lookfor = [ split ',' => ( $lookfor || '' ) ];
$pattern ||= '';

my @search_in;

if ( !@ARGV ) {
    @search_in = ( dir => '.' );
}
elsif ( 1 == @ARGV && -d $ARGV[0] ) {
    @search_in = ( dir => $ARGV[0] );
}
else {
    @search_in = ( files => [ @ARGV ] );
}

my $grepl = App::Grepl->new(
    {
        look_for      => $lookfor,
        pattern       => $pattern,
        warnings      => $warnings,
        filename_only => $filename_only,
        @search_in,
    }
);
$grepl->search;

Now that's how you write a program. The only logic is processing command line arguments and passing them to the application.

Yes, the constructor is doing a lot, but even that's fairly easy to manage. I have about 96% test coverage and I'm not worried about having code in my program which is difficult to test (unlike in, say, runtests).