Re: not-so-plain documentation
# The following was supposedly scribed by # Caleb Epstein # on Tuesday 29 June 2004 11:27 pm: -f, --force, --noforce force overwrite of existing files (default: no) I assume that for this module to know that --noforce is viable, you mistakenly omitted the ! at the end of 'f|force!'? Yes. I was copying into the email while simultaneously revising my code:) Documentation that arguments are array-refs (@) are which can be specified multiple times would be a neat feature, too. I'm not sure what you mean by this. That the help message should mark options as arrays and hashes? I'm not sure that I want that to be so automatic (maybe just a list of symbols at the end of the line (e.g. s@ for string array?)) Well, the help_string() function is operable now and into the subversion repo at http://ericwilhelm.homeip.net/svn/Getopt-Helpful/trunk/code/Getopt/ I tried to use the Getopt::Long::ParseOptionSpec() function, but ended up with some naive regex operations instead. If you have svn, you can take a look a couple of versions back. It wasn't very pretty. The only magic that currently happens is related to the third argument in the rows given to new(). When you make a help_string(), you get your option name in 's unless the option had no type (boolean) or you had passed an explicit 'arg is a file' kind of string. my $hopt = Getopt::Helpful-new( ['n|name=s', \$name, '', # -- here arg string is undef name for new part], ['p|parts=s', \$parts, 'parts dir', # -- this one is explicit directory containing parts (default $parts)], ); print $hopt-help_string; This prints: options: -n, --name name name for new part -p, --parts parts dir directory containing parts (default parts/) --Eric -- These crispix get soggy so quickly. -- Tina Connolly
Re: not-so-plain documentation
Eric Wilhelm [EMAIL PROTECTED] writes: I'm not super happy with the array-reference interface (it assumes a lot and lines tend to need a lot of re-wrapping), but it gets everything into one place rather than scattered about and allows the variables to tell the user their default values (even solving the side-effect that Johan pointed out.) It also allows you to maintain an order, which a hash wouldn't. I have experimented with: GetOptions(create|c?create a new archive = \$create, color=i{3}(0..255)?color components = [EMAIL PROTECTED], ... ); The user-friendlyness dropped quickly with the power added. The ultimate solution would be to have individual objects for each option, like I once tried with the (still stillborn) Getopt::Long TNG: my %opt = (); my $p = new Getopt::Long -Config = [qw(noignorecase bundling)], -Linkage = \%opt; $p-add (new Getopt::Long::Option -Name = 'concatenate', -Aliases = ['catenate','A'], -Help = 'append tar files to an archive'); $p-add (new Getopt::Long::Option -Name = 'create', -Aliases = ['c'], -Help = 'create a new archive'); $p-add (new Getopt::Long::IntOption -Name = 'block-size', -Aliases = ['b'], -Help = 'block size of nx512 bytes (default n=20)'); $p-add (new Getopt::Long::StringOption -Name = 'directory', -Aliases = ['C'], -Help = 'change to directory dir'); unless ( $p-parse ) { $p-usage (-indent = 4, -hang = 12, -width = 60, -longprefix = --, -shortprefix = -); } This would produce: --concatenate --catenate -C append tar files to an archive --create -c create a new archive --block-size=n -B block size of nx512 bytes (default n=20) --directory=dir -C change to directory dir But then you'll want other texts, and empty lines, and so on. Usage: album [options] [ directory ] Album: --info XXX description file, default info.dat (if it exists) --title XXX album title, default Photos Index: --cols NN number of columns per page, default 4 --rows NN number of rows per page, default 3 --thumbsize NNN the max size of thumbnail images, default 200 --captions XXX f: filename s: size c: description t: tag There's always a next hop... -- Johan
Re: not-so-plain documentation
# The following was supposedly scribed by # [EMAIL PROTECTED] # on Saturday 26 June 2004 05:31 am: Andy mentioned Getopt::Declare. I've briefly taken a look at it a few times, and I did so again when he mentioned it. I guess I never really got it. It doesn't seem to solve the problem, but since I've been thing about tighter perl/pod integration, it occurs to me that a natural extension of Getopt::Decare's functionality would be to have it get its specification from pod It's an interesting functionality, but the trouble with having the options come from the pod is that you don't get to make perl do any of the work. I've taken a crack at this and it seems that maybe its a two-part problem. Part one is tying the documentation to the option declaration, while part two is dynamically generating the pod (yes, Getopt::Declare skips part two, but again, I'm stubborn and want to make the computer earn its keep.) This is only partly underway, but feel free to look at the bloody stump of code at http://ericwilhelm.homeip.net/svn/Getopt-Helpful/trunk/code/Getopt/ $example = 'END'; use Getopt::Long; # this doesn't replace Getopt::Long, just supplements it use Getopt::Helpful; my $name; my $ext = .dwg; my $parts = parts/; my $force = 0; my $hopt = Getopt::Helpful-new( ['n|name=s', \$name, 'name', name for new part], ['p|parts=s', \$parts, 'parts dir', directory containing parts (default $parts)], ['e|ext=s', \$ext, '.extension', extension for geometry file (default $ext)], ['f|force',\$force, ' ', force overwrite of existing files (default: . ($force ? yes : no) . )], ); GetOptions( $hopt-opts, ); END The documentation part isn't ready yet, but it would be something like $hopt-help_string() and would return a string which joins the 0,2, and 3 indices of the input data (padding the columns and maybe turning 'f|force' into '-f, --force', giving something like: -e, --ext extension extension for geometry file -f, --force, --noforce force overwrite of existing files (default: no) I'm not super happy with the array-reference interface (it assumes a lot and lines tend to need a lot of re-wrapping), but it gets everything into one place rather than scattered about and allows the variables to tell the user their default values (even solving the side-effect that Johan pointed out.) It also allows you to maintain an order, which a hash wouldn't. Also, I'd welcome suggestions on the name, since Getopt:: doesn't really describe the functionality (except that it is related to option getting.) --Eric -- Cleanliness is next to impossible. --Unknown
Re: not-so-plain documentation
On Tue, Jun 29, 2004 at 09:50:06PM -0500, Eric Wilhelm wrote: my $hopt = Getopt::Helpful-new( [...] ['f|force',\$force, ' ', force overwrite of existing files (default: . ($force ? yes : no) . )], [ ... ] -f, --force, --noforce force overwrite of existing files (default: no) I assume that for this module to know that --noforce is viable, you mistakenly omitted the ! at the end of 'f|force!'? Documentation that arguments are array-refs (@) are which can be specified multiple times would be a neat feature, too. I'm a huge fan of Getopt::Long and all its powerful abilites. This would be a nice complement. -- Caleb Epstein | bklyn . org | I got the bill for my surgery.Now I know cae at| Brooklyn Dust | what those doctors were wearing masks for. bklyn dot org | Bunny Mfg. | -- James Boren
Re: not-so-plain documentation
On 6/25/2004 10:47 AM, Eric Wilhelm wrote: # The following was supposedly scribed by # Randy W. Sims # on Thursday 24 June 2004 10:40 pm: You'll want to subclass Pod::Text, override the proper method to add a new escape sequence (say $variable_name), then maybe override the constructor to take a hash with the values for the variables or possibly something more elaborate like evaling the variable name in the caller's context. Yes. The trouble is that I don't want to have to manually re-generate the pods in any way, so I'll need a modified perldoc. (If you haven't chastised me for it before, I'm the guy who makes changes to the code directly on the production system:) My concept is that the script does something like 'use Pod::Dynamic' and builds some pod sections (or defines some variables) by running up to some point when $Pod::Dynamic::pod_mode is true. This means that 'dynperldoc' can simply do() the file and have some variables defined for use in generating the fully-formed pod. So, if the variables are changed to some other defaults, both 'dynperldoc script' and 'script --help' show the same values without having to manually regenerate anything. Integration with perldoc is something you'll have to run by Sean and P5P. Basically, this would require a change to the pod spec or at least a mechanism for arbitrarily extending it. I would avoid a personalized perldoc as this is problematic for all the reasons forked software is problematic. (I speak from experience, having created several customized spin-offs for private use.) I've done similary on several occasions and it is fairly trivial. If you have trouble, I can probably dig up an example. I may take you up on that. CPAN's results for 'dynamic pod' are depressing. Below is an example that shows how you might go about creating a new pod escape sequence. Note that if you run the below script through perldoc, it will ignore the unknow sequence, printing nothing. Another idea is to use a source filter. I wrote a small demo of that technique (using Filter::Simple), but I couldn't get it to filter within the POD section even though it is documented to do so with the correct arguments. It would still have the same problem as the above method though. Andy mentioned Getopt::Declare. I've briefly taken a look at it a few times, and I did so again when he mentioned it. I guess I never really got it. It doesn't seem to solve the problem, but since I've been thing about tighter perl/pod integration, it occurs to me that a natural extension of Getopt::Decare's functionality would be to have it get its specification from pod, so that something like the following would serve for the spec to getopt: =head1 OPTIONS =over =item B--option arg an option with a required argument =item B-v verbose output =item B--verbose [ditto] =back __END__ And, here is the example for extending POD #!/usr/bin/perl package Pod::X; use strict; use Pod::Text; our @ISA = qw(Pod::Text); our $VERSION = 1.0; sub interior_sequence { my ($parser, $seq_command, $seq_argument) = @_; # Can create custom sequences using matching [A-Z]... if ( $seq_command eq 'X' ) { # move up thru stack until we get the name of the calling package my $stack_frame = 0; ++$stack_frame until (caller($stack_frame) !~ /^Pod::/); my $calling_pkg = caller($stack_frame); # evaluate the variable as a package variable of the calling package return eval \$${calling_pkg}::${seq_argument}; } else { # otherwise not a custom sequence, so delegate to SUPER return $parser-SUPER::interior_sequence($seq_command, $seq_argument); } } 1; package main; use strict; use warnings; our $VERSION = 0.01; my $parser = Pod::X-new(); $parser-parse_from_file($0); =head1 NAME pox - Pod eXtension Test =head1 VERSION pox XVERSION __END__ Regards, Randy.
Re: not-so-plain documentation
* Eric Wilhelm [EMAIL PROTECTED] [2004-06-25 05:11]: I've seen pod2usage() and this would work, but most of these scripts have some defaults set for variables that can be changed with the GetOptions flags and I'd like to show these defaults at least in the help message. You are looking for Pod::Constants. http://search.cpan.org/dist/Pod-Constants/ Regards, -- Aristotle If you can't laugh at yourself, you don't take life seriously enough.
Re: not-so-plain documentation
my $rounding = 0.01; GetOptions( 'round=f' = \$rounding, 'help' = sub {usage()}, ); sub usage { print usage: $0 filename\n; print options: --round float (default $rounding)\n; } END This will have a nasty side effect, as shown below: $ round --help usage: round filename options: --round float (default 0.01) $ round --round=42 --help usage: round filename options: --round float (default 42) -- Johan
Re: not-so-plain documentation
A. Pagaltzis wrote: * Eric Wilhelm [EMAIL PROTECTED] [2004-06-25 05:11]: I've seen pod2usage() and this would work, but most of these scripts have some defaults set for variables that can be changed with the GetOptions flags and I'd like to show these defaults at least in the help message. You are looking for Pod::Constants. Or even Scriptalicious... http://search.cpan.org/dist/Scriptalicious/ -- Sam Vilain, sam /\T vilain |T net, PGP key ID: 0x05B52F13 (include my PGP key ID in personal replies to avoid spam filtering)
Re: not-so-plain documentation
# The following was supposedly scribed by # Johan Vromans # on Friday 25 June 2004 03:00 am: This will have a nasty side effect, as shown below: $ round --round=42 --help usage: round filename options: --round float (default 42) Yes, this is correct. But I was planning something more along these lines: use Getopt::Long; my $all = 7; my $foo = bar; my @opt_build = ( ['a|all=i', \$all, value for all (default $all)], ['f|foo=s', \$foo, string for foo (default $foo)], ['h|help' , sub { usage()}, show this help message], ); my %opts = map({$_-[0] = $_-[1]} @opt_build); my @help = map({$_-[0] $_-[2]} @opt_build); GetOptions(%opts); sub usage { my $caller = $0; $caller =~ s#.*/##; die join(\n, usage:, $caller file, @help), \n; } END And, in my mythical modified version of perldoc, I'd need to run up to the point where @help is declared, then exit. Maybe instead of 'my @help=', we do 'Pod::Dynamic-usage(map({$_-[0] $_-[2]} @opt_build));' and that triggers an exit from the 'do()' (for instance when ($0 =~ m/perldoc/)), and declares main::usage() otherwise. Something along those lines anyway. --Eric -- Peer's Law: The solution to the problem changes the problem.
Re: not-so-plain documentation
# The following was supposedly scribed by # Randy W. Sims # on Thursday 24 June 2004 10:40 pm: You'll want to subclass Pod::Text, override the proper method to add a new escape sequence (say $variable_name), then maybe override the constructor to take a hash with the values for the variables or possibly something more elaborate like evaling the variable name in the caller's context. Yes. The trouble is that I don't want to have to manually re-generate the pods in any way, so I'll need a modified perldoc. (If you haven't chastised me for it before, I'm the guy who makes changes to the code directly on the production system:) My concept is that the script does something like 'use Pod::Dynamic' and builds some pod sections (or defines some variables) by running up to some point when $Pod::Dynamic::pod_mode is true. This means that 'dynperldoc' can simply do() the file and have some variables defined for use in generating the fully-formed pod. So, if the variables are changed to some other defaults, both 'dynperldoc script' and 'script --help' show the same values without having to manually regenerate anything. I've done similary on several occasions and it is fairly trivial. If you have trouble, I can probably dig up an example. I may take you up on that. CPAN's results for 'dynamic pod' are depressing. Thanks, Eric -- Left to themselves, things tend to go from bad to worse. --Murphy's Corollary
Re: not-so-plain documentation
On 6/24/2004 11:11 PM, Eric Wilhelm wrote: Hi everybody! I'm going to be documenting a system of (30+) programs with is mostly scripts, rather than modules. I know you can just put pod text in your scripts, but I'd like to also integrate the usage messages into the pods (or get them from the pods.) I've seen pod2usage() and this would work, but most of these scripts have some defaults set for variables that can be changed with the GetOptions flags and I'd like to show these defaults at least in the help message. Example: my $rounding = 0.01; GetOptions( 'round=f' = \$rounding, 'help' = sub {usage()}, ); sub usage { print usage: $0 filename\n; print options: --round float (default $rounding)\n; } END Since the strings printed by usage() in this case are generated on the fly, the values which have already been set are available to be printed. With pod2usage() and perldoc, this is not the case. Is there any way to make this work without having to maintain duplicate information? Preferably, something that would try to do() the file up to a certain point, gather the variables and perform a substitution (maybe on a tag like v$rounding.) Yeah, I alway thought that was a weakness of the core pod modules. Fortunately, it's easy to subclass them to do what you want. You'll want to subclass Pod::Text, override the proper method to add a new escape sequence (say $variable_name), then maybe override the constructor to take a hash with the values for the variables or possibly something more elaborate like evaling the variable name in the caller's context. I've done similary on several occasions and it is fairly trivial. If you have trouble, I can probably dig up an example. Randy.
Re: not-so-plain documentation
I've seen pod2usage() and this would work, but most of these scripts have some defaults set for variables that can be changed with the GetOptions flags and I'd like to show these defaults at least in the help message. Take a look at, I believe, GetOpt::Declare. It's one of Damian's. xoxo, Andy -- Andy Lester = [EMAIL PROTECTED] = www.petdance.com = AIM:petdance