run() module, run()
Eric Wilhelm
scratchcomputing at gmail.com
Sat Feb 17 18:06:58 GMT 2007
# from Edmund von der Burg
# on Saturday 17 February 2007 05:21 am:
>This would be comprised of a core module that deals with parsing the
>command line arguments and then hands over to plugins to do the actual
>work. The actual script would just 'use' the core module and then call
>its 'run' method.
I agree that code should be modularized, but I have to say that I'm not
a fan of this Module->run() architectural style. I think it leads to
inflexible code because too much functionality gets balled-up into one
place.
While I haven't exactly nailed-down a theory of modularizable, testable
script style, I have been working in that direction for a while now.
So, take the following as half-baked or whatever, but I do think the
run() scheme has a lot of room for improvement -- particularly in
agility and reuse.
The run() scheme can be tolerable IFF your code is broken into App::CLI
style modules, but sometimes that seems a bit heavy, particularly when
a project is first taking shape.
With a single module designed to be entered from a single run() method,
I think too much of what wants to be in the program ends up in the
module. At that point, why have a module? Just to be able to test it?
I don't think this justifies it, as testing a properly structured
program is just like testing a module.
I want module API's to be made of small parts, with at least
contructors, aliases/dispatch, options, and arguments handled in the
frontend program code.
What happens when you (or another programmer) need to put a second
frontend on the module? Does it need a run2 method? Or, does the
other programmer need to copy and paste the argument processing done in
run() to replicate the functionality. I think the run() method can
easily become too difficult to refactor.
What about aliased commands? Does Module->run() check $0? What about
command-line arguments? Does Module->run() check @ARGV (or call
GetOptions(), which checks @ARGV.) I think having program-specific
globals in a module can easily make it difficult to trace. Plus, that
code is going to naturally tend away from flexibility rather than
toward it.
Some examples of my recent style:
* no module, no functions, everything in bin::famwatch::main()
http://scratchcomputing.com/svn/misc/trunk/code/perl/bin/famwatch
* same as above, but with a CPAN module
http://scratchcomputing.com/svn/wx_hacks/trunk/code/perl/bin/wxdo
* module, dispatcher, still in one file
http://scratchcomputing.com/svn/code_utilities/trunk/code/perl/bin/podadz
* module, dispatcher, multiple files
http://scratchcomputing.com/svn/App-YmlDB/trunk/bin/ymldb
--Eric
--
[...proprietary software is better than gpl because...] "There is value
in having somebody you can write checks to, and they fix bugs."
--Mike McNamara (president of a commercial software company)
---------------------------------------------------
http://scratchcomputing.com
---------------------------------------------------
More information about the london.pm
mailing list