Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re^2: Command line tool coding style?

by Aristotle (Chancellor)
on Jan 16, 2002 at 05:34 UTC ( #139119=note: print w/ replies, xml ) Need Help??


in reply to Re: Command line tool coding style?
in thread Command line tool coding style?

Two reaons: strict and the GetOptions() hash. The latter was actually what gave me the idea in the first place. The script started out having a series of

{ do_this(\%options, $table), last if $action eq 'this'; do_that(\%options, $table), last if $action eq 'that'; # ... die "Usage here\n"; }
Look a bit harder and you'll see method calls in disguise.. With this new approach, all I have to do is write sub _more {} and the script will automatically understand the "more" option - and it works with strict too. (Plus can $execute $_action looks much prettier than defined &$_action IMHO :-))


Comment on Re^2: Command line tool coding style?
Download Code
Re: Re: Re: Command line tool coding style?
by perrin (Chancellor) on Jan 16, 2002 at 07:43 UTC
    You can easilly get by strict if you use this:
    eval('&' . $action . '()'); if( $@ ) { die "Usage\n"; }
    It might be good to check the text of the exception here to make sure it's from a missing sub. You might even be able to do this:
    my $subref = \&{$action}; die "Usage" unless defined &$subref();
    I haven't tried that last though.

    There's just no good reason to use OO here, and it makes the code more confusing and JAPH-ish. Maybe there's something else in your program that justifies OO, but this problem doesn't.

    Incidentally, a nicer way to write that dispatch table from your above comment would be something like this (untested):

    my %dispatch = ( 'this' => \&do_this, 'that' => \&do_that, ); if (defined $dispatch{$action}) { &$dispatch{$action}; } else { die "Usage\n"; }

      I actually agree it is sort of JAPHish - that's why I posted it as a question here. I went through thinking about a dispatch table exactly the way you proposed, as I already explained in my reply to chromatic, but it has the same problem as the switch-construct: adding an "action handler" requires maintaining the dispatch table. I could have put the handlers as anonymous subs right into the dispatch table, but then I have to define them before the body of the main program and they're very long. (The biggest one is 2.5 pages of straight-through code without any loops.)

      I sort of like your eval proposition, though the idea of circumventing strict in whichever fashion irks me. :-)

      Thinking about it some more I think the sole reason it turns JAPHish is the role I have given to new() - that's the single thing I would point out as contrived in retrospect. I wonder if it's possible (and what you'd think) of doing something along the following lines:

      #!/usr/bin/perl use warnings; use strict; print "\nfoo script\n\n"; my $action = shift(@ARGV); die "Usage here\n" unless $action; my $handler = can main "_$action"; die "Unknown action '$action'\n\nUsage here\n" unless ref $handler; my %params; GetOptions(\%params, qw(various options here)); # do more stuff with %params here $handler->(\%params); exit; ###################################################################### +## ###################################################################### +## use Getopt::Long; # use Other::Modules::Here; # .. etc ..
        I'd suggest moving the "use Getopt::Long" to the top part, since that's where you actually use the module, and giving the lower section a real package name ("package MyTool" or something). Then instead of this:
        my $handler = can main "_$action";
        you can have this: this:
        my $handler = MyTool->can("_$action");
        Easier to follow, in my opinion.

        Incidentally, a nice way to code tools like this is to make a separate module that implements all of the real logic, and then a CLI wrapper that just calls that module's methods. Then you can easilly add a GUI, call it from CGI, etc.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://139119]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (9)
As of 2014-09-18 22:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (125 votes), past polls