From: Uri Guttman <[EMAIL PROTECTED]>
Date: Fri, 10 Sep 2004 01:37:14 -0400
>>>>> "BR" == Bob Rogers <[EMAIL PROTECTED]> writes:
BR> But this morning, I had an idea for Pod::CLOD while showering.
BR> (That's a good sign; some of my best ideas come to me in the shower.)
so you aren't a filthy bastard then? :)
Correct. (Or at least half correct . . . at least for the rest of that
morning . . . ;-)
it makes more sense. but i will offer something very interesting (IMO
:) and very old but it might be more like what you want. when i
first shifted from perl4 to 5 i wrote an arg parser using refs and
such as an exercise as well as to claim that i also wrote another arg
parser. i never cpan'ed it as i would want to do a full rewrite of
parts (make it more OO and clean up stuff). its advantage to you is
that it is driven by a list of hashes that describe each option . . .
Yes, this is clearly a more versatile data structure. You could even
merge options, i.e. adding synonyms or mutexes if a name collision was
found when producing the name-to-opt hashes.
Of course, if you're storing things in hashes, you might as well make
them instances, and they they could merge themselves. But perhaps
that's what you meant by "make it more OO".
But this is all overkill for me. Since I can get what I need with a
minor gloss on the data structures that Getopt::Long accepts, I have
little reason to change the representation, especially since it would
mean thoroughly reworking 400-odd lines of command_line_options code.
On the other hand, this is not an either/or proposition. A
command_line_options method could return a Pod::CLOD::Option instance as
the value, if it wanted complete flexibility, or it could return
anything else, and the option parser would create a Pod::CLOD::Option
descriptor with appropriate defaults. I may in fact do something like
this; it's compatible with what I'm doing now, and probably less painful
to design it this way from the start. If experience is any guide, I'm
gonna want something like this some day . . .
BR> I could then handle delegation with a special option name:
BR> -delegate => $delegated_object
BR> and the Pod::CLOD option processing would know to ask
BR> $delegated_object for its command_line_options list. The
BR> -delegate keyword shouldn't interfere with anything GetOptions
BR> would accept, and could be repeated, causing the delegate's list
BR> to be processed at the point it was encountered.
this sounds like an include mechanism for arg descriptions.
Yes.
BR> This should give each command_line_options method full control
BR> over how its options are constructed, while allowing Pod::CLOD to
BR> do all the hairy parts. It also means that I would know exactly
BR> which classes contributed which options, which should make it
BR> easier to get the right option documentation strings.
i think that is pretty much what i just described but with a different
way to do the work.
Yes, though I like putting the work into Pod::CLOD. One advantage to
doing so is that I could add (hold on to your hats) an --option-debug
option that turns on debugging output in the option parser. Then all of
the internal magic can be made transparent without having to tweak
anything in the command_line_options methods. I am expecting to need
this anyway in order to get it all working reliably.
you can find this 7 year old (but amusing) argv parser here:
http://sysarch.com/perl/Argv.pl
i can see many ways to improve and shred the code. i would me just as
mean to myself as i am to others! :) so go ahead shred away if you
want . . .
Thanks for the URL; I'll continue to study it, but I think I'll pass on
the full-scale shredding. Besides, it seems unfair to pick on something
written when your perl5 style was still evolving. Not to say pointless
-- I doubt I could find much worth mentioning that you don't already
know about. (Unless, of course, you are *asking* to be shredded. ;-)
But, at the risk of being pointless and unfair, I will pointlessly
take unfair advantage of this opportunity to soapbox my views on
whitespace, comments, and code information density, mentioned only
briefly in previous emails.
<soapbox>
Frankly, I find Argv.pl hard to read -- we are poles apart on
commenting and indentation style (or were, given that this may not be
anything like your current style). It's mostly a question of
information density -- I am used to reading code with high information
density. Partly, this is my failing; I am too easily distracted by
noise, so I try to keep the noise level as low as possible in the code
that I write. (By the same token, I also can't hold a conversation in a
room with a TV, because the TV keeps sucking me in, as it is designed to
do, and I trail off in mid-sentence. I don't watch TV myself, and so I
haven't trained myself to ignore it; regular TV watchers seem to be able
to ignore the stupid thing with ease. This is probably a defense
mechanism.)
The Parse sub is a prime example of what I would consider
counterproductive code decoration. It violates the first rule of
commenting, namely that comments should say something about the code
that is not obvious:
# Argv's main external routine
sub Parse {
( $opt_list_ref, $control_hash_ref ) = @_ ;
# check that the options descriptions is a ref to an array
if ( ref $opt_list_ref ne 'ARRAY' ) {
die "Options ref is not ARRAY, it is ",
ref $opt_list_ref, "\n" ;
}
# parse the control hash ref
&parse_control ;
# preprocess the option descriptions
&preprocess_opt_list ;
# parse @ARGV for options
&parse_argv ;
# assign option values and defaults to their variables
&assign_opt_vals ;
# put the permuted argument in the front of @ARGV
unshift( @ARGV, @argv_permuted_args ) ;
}
The vertical space is mostly wasted, since the line count has been
doubled with mostly redundant comments, and redoubled it with equally
pointless blank lines. The last comment that pertains to a sub call is
the only one that actually adds information that can't be deduced from
the sub name. In fact, you'd have been better off if you had used the
comment text as the sub names:
# Argv's main external routine
sub Parse {
( $opt_list_ref, $control_hash_ref ) = @_ ;
# check that the options descriptions is a ref to an array
if ( ref $opt_list_ref ne 'ARRAY' ) {
die("Options ref is not ARRAY, it is ",
ref $opt_list_ref, "\n") ;
}
&parse_control_hash_ref ;
&preprocess_option_descriptions ;
&parse_ARGV_for_options ;
&assign_option_values_and_defaults_to_variables ;
# put the permuted argument in the front of @ARGV
unshift( @ARGV, @argv_permuted_args ) ;
}
This keeps the basic structure and perl4-ish syntax intact to make it
easier to compare; passing explicit arguments to these subs would make
their purpose and operation even clearer. I left in three blank lines
that separate the code into arg parsing, arg validation, main
processing, and cleanup sections. But I would probably not even bother
with the last two in a sub so short.
Even so, I have cut the number of lines in half without losing much
information (if any), which means the information density is twice as
high. If done for the rest of the code, I suspect the amount of
scrolling I would need in order to study it would be cut by more than
half. And less time scrolling means more time reading, which ought to
be an advantage even if you do not agree that the "condensed" version is
easier to read.
</soapbox>
-- Bob Rogers
http://rgrjr.dyndns.org/
_______________________________________________
Boston-pm mailing list
[EMAIL PROTECTED]
http://mail.pm.org/mailman/listinfo/boston-pm