Subject: | Confusing doc layout |
I gave rjbs my impressions from my first encounter with App::Cmd. Its
in his chat log. He said to bug it. Here it is.
Michael Schwern: Got a moment to hear App::Cmd feedback?
rjbs: sure thing
Michael Schwern: So I sat down to write something like "gitpan clone
<dist>" and "gitpan fork <dist>" and remembered hdp and Eric arguing
over App::Cmd.
Michael Schwern: So I looked.
Michael Schwern: From the docs the basics looked straightforward, though
overkill for a small app so I did everything in one file with "package"
statements.
Michael Schwern: And I quickly hit my first stumbling block
rjbs: yeah, did that work?
Michael Schwern: opt_spec isn't documented
Michael Schwern: global_opt_spec is barely documented
rjbs: the global one I didn't write; I know it's poorly documente d:(
rjbs: I don't even exactly understand why it's there.
Michael Schwern: I wanted to add some flags to apply to all commands
rjbs: http://search.cpan.org/dist/App-Cmd/lib/App/Cmd/Command.pm#opt_spec
Michael Schwern: Ahh, the "its in the OTHER man page" problem
rjbs: yeah; you're writing a method for a App::Cmd::Command subclass
rjbs: did you read the tutorial, btw?
Michael Schwern: Which is not obvious
Michael Schwern: Yeah, the tutorial contradicted the synopsis
rjbs: looks like Tutorial could use a few L<>'s added
rjbs: o?
Michael Schwern: The tutorial says "use App::Cmd::Setup -app"
Michael Schwern: err
Michael Schwern: Ahh, the tutorial says "use App::Cmd::Setup -app" but
in the tip to add a --help option it says "use App::Cmd::Setup -command"
without explaination.
Michael Schwern: While I'm at it, why am I writing validate_args()?
rjbs: in that example?
Michael Schwern: In any example
rjbs: you don't need to
rjbs: if you don't provide it, validation is "okay"
Michael Schwern: then pull it
rjbs: what?
Michael Schwern: Wait, it doesn't do any validation?
rjbs: ...
rjbs: Okay, let me tell you waht happens
rjbs: and you tell me how to fix hte docs.
rjbs: You write an opt_spec which is just passed verbatim to
Getopt::Long::Descriptive.
rjbs: it turns @ARGV into $opt and $args
rjbs: $opt will tell you what all the switches were, like:
if ($opt->verbose) { ... }
rjbs: $args is an arrayref of all the stuff left over
rjbs: so: myapp cmd --verbose --protocol tcp myfile
might leave $args = [ 'myfile' ]
rjbs: so the validate args there is saying: before you go any further,
if the user said --help, give a help message.
Michael Schwern: So this is in addition to Getopt::Long::Descriptive's
checks
rjbs: yes
rjbs: GLD validates switches.
Michael Schwern: Ahh, that's not obvious
rjbs: validate_args validates what's left over.
rjbs: Ok.
rjbs: So, I will insert some more documentation above the paragraph
beginning "The first two methods"
Michael Schwern: I think part of the problem is the App::Cmd page
presents itself as "here, its easy!" and then there's a bunch of
documentations for lots of methods not mentioned before and little no
documentation for the methods already mentioned.
Michael Schwern: (man, my fingers are not working)
rjbs: nor mine; they're cold
Michael Schwern: What is the criterion for the methods documented in
App::Cmd?
rjbs: They're methods on the App::Cmd subclass.
rjbs: or the base class, depending on how you look at it.
rjbs: If you write a program "svn" and it has subcommands "commit" and
"update"
Michael Schwern: Part of the confusion is the "use YourApp -command"
cuteness.
rjbs: then App::Cmd is the base class of the thing implementing "svn"
rjbs: App::Cmd::Command is the base class of the thing implementing
"commit' and "update"
Michael Schwern: Yeah, that's non-obvious
rjbs: the -command thing makes sense, I promise -- but clearly it needs
clearer explanation
Michael Schwern: It obscures what I'm actually subclassing so I don't
know where to look next for documentation.
Michael Schwern: That App::Cmd::Setup is documented adds to the confusion
rjbs: You don't need to do things that way.
rjbs: ugh, I know, that DESPERATELY needs docs
Michael Schwern: s/documented/undocumented/
rjbs: Everything Just Works if you just use base.
Michael Schwern: Then just use base.
rjbs: no
Michael Schwern: Then just use parent
rjbs: (a) "Everything" was an overstatement; the plugin subsystem wont' work
rjbs: (b) it's actually very very convenient to not just use base, once
you know how App::Cmd::Setup works
rjbs: the plugin subsystem needs to track registered subcommands, etc
rjbs: so it needs to use something that will register with the superclass
Michael Schwern: You write plugins infrequently enough that I think two
lines is ok
Michael Schwern: You're optimizing the wrong bit
rjbs: It would be two lines in every command, and would have to happen
at compile time.
Michael Schwern: I thought you said it only effected plugins
rjbs: so now it's like BEGIN { __PACKAGE__->register_with_etc }
rjbs: no, it allows plugins to affect command subclasses
Michael Schwern: oh, you're doing some sort of wrapper/hijacking of
command methods?
rjbs: basically, the plugin system allows the command to cause a
compile-time import into every command subclass to give things subs
rjbs: so you can end up writing:
rjbs: sub execute {
exit unless prompt_yn("Really???");
rjbs: and prompt_yn is a sub available everywhere because Your::App
provides it to all subcommands
rjbs: ...but I don't think any of this should really be a big deal. If
we go back to the original confusion that occurred, it was "where do I
figure out wtf methods I need to write."
rjbs: which the tutorial can be clearer about pointing to, as can the
main docs
Michael Schwern: I would put all the basic user-facing methods in
App::Cmd and bury the rest in their respective documentation.
Michael Schwern: Also, what's the last argument to describe_options() in
Getopt::Long::Descriptive?
rjbs: some nightmarish thingI don't remember; I didn't write it :)
rjbs: but I can look it up
rjbs: all I -ever- do is:
Michael Schwern: Oh, that's HDP's fault
rjbs: describe_options("%c %o", [...], [...], ...)
rjbs: and never the final magic thingy
rjbs: I think what I really need is a new document, App::Cmd::Manual
rjbs: which is more thorough than ::Tutorial, more a reference
rjbs: and covers every class you need to care about
rjbs: because I really do wnat each class to document itself normally
rjbs: and I can put a big pair of links atop the other classes
"SERIOUSLY YOU PROBABLY WANT THE MANUAL"
Michael Schwern: Yes
Michael Schwern: So my impression at this point is "that's great, uhh,
I'm going to hack it together myself"
rjbs: ?
Michael Schwern: There's just a bit too much hidden magic in App::Cmd.
Michael Schwern: For something that I can write in three subroutines and
a hash.
rjbs: I agree that there are too many underdocumented bits.
Michael Schwern: I see where its going though
rjbs: I don't agree that you can really do what it does in three
subroutines and a hash. ;)
rjbs: I do appreciate feedback on where its docs are lacking, and I
always try to improve the docs as soon as I get feedback.
rjbs: If you have specific questions, I can answer those, to.
rjbs: too
rjbs: probably what I will do is try to make an outline of Manual.pm
this weekend.
rjbs: do you think that's a bad plan?
rjbs: (Manual.pm)
Michael Schwern: I can do what I need in three subroutines and a hash.
rjbs: right.
Michael Schwern: The argument checking won't be perfect, because it
won't be per command.
Michael Schwern: OIC, the Getopt::Long::Descriptive documentation is
layed out weird.
rjbs: Well, is something actually preventing you from using App::Cmd?
Obviously, I don't get a dollar if you do or anything.
rjbs: How so? I didn't write those docs, nor do I remember how they're
written.
rjbs: I should look at them.
Michael Schwern: Its written almost like its the docs for a program.
Michael Schwern: So it has major sections about describe_options()
Michael Schwern: But then it has regular function documentation for
desribe_options()
rjbs: I see.
rjbs: Yeah, okay.
rjbs: These docs need to be overhauled.
Michael Schwern: So if you just search for "describe_options" you'll
skip over all the real docs
rjbs: I really have barely looked at them, ever, since I had to learn
how it worked before they existed (at work).
rjbs: yeah, that sucks
Michael Schwern: The describe_options() docs point back to the SYNOPSIS,
which is not where the meat is.
rjbs: ha
Michael Schwern: Oh, and the greatest curse of all. "Option
specifications are the same as in Getopt::Long" which are a nightmare to
find in the Getopt::Long docs!
Michael Schwern: Ok, I'm done bitching now
rjbs: I was thinking the EXACT SAME THING
rjbs: I'm going to summarize them in GLD.
rjbs: because I can never find WTF I want in Getopt::Long.
rjbs: EVER
Michael Schwern: Want me to RT any of this?
rjbs: sure! put a ticket in app-cmd, and you can just refrence our chat
and I'll be able to pull it out of logs later in case I forget. thanks1
rjbs: btw
rjbs: I wrote App::Cmd because I wanted something with good
documentation. :-)
rjbs: the pre-existing system was...
rjbs: http://search.cpan.org/~ALEXMV/App-CLI/