Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re: Re: Re: Command line tool coding style?

by perrin (Chancellor)
on Jan 16, 2002 at 07:43 UTC ( #139132=note: print w/ replies, xml ) Need Help??


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

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"; }


Comment on Re: Re: Re: Command line tool coding style?
Select or Download Code
Re^4: Command line tool coding style?
by Aristotle (Chancellor) on Jan 16, 2002 at 17:40 UTC

    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.

        Ops, forgot to move the Getopt::Long when I restructured the code - of course it belongs at the top.

        Good point about the extra package as well - I had a package Logic; and package Utils; at first, but it made the code in Logic awfully bulky if I didn't import all the utility functions. Now that I have a naming convention for the handlers it is quite effortlessly possible to use a package once again - handlers and utility functions can be distinguished quite easily. What's left in main is just the initialization skeleton then.

        I'm well aware of the points to be made for proper modularization (I tend to modularize too much actually - one of them hubris people is me, not a lazy one).

        It is obviously necessary to always remember under which premises one took certain decisions and to go back and reassert them as one simplifies one's code. Thanks for helping me find the proper way. :-)

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others imbibing at the Monastery: (4)
As of 2014-08-02 08:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Who would be the most fun to work for?















    Results (55 votes), past polls