Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
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
Replies are listed 'Best First'.
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 making s'mores by the fire in the courtyard of the Monastery: (14)
As of 2015-07-31 21:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (282 votes), past polls