From: Bardur A. <oca...@sc...> - 2004-08-13 16:52:28
|
Hi all, As promised, here's my take on how option parsing should be done (i.e. Python optparse-style). Since there's quite a lot of it, I've uploaded the code to http://imada.sdu.dk/~bardur/optparse-20040813.tar.gz Currently I'm using an everso slightly modified Getopt as the backend to actually parse the command line, but I'll change away from that and implement my own because of a couple of limitations in that parser which prevent me from implementing some of the optparse stuff (nargs>1 support comes to mind). There is a complete example in the tarball, but here's a sample from that file (revised syntax, sorry but I've gotten so used to it that I daren't try my hand at 'old' syntax): open OptParse; [...] let op = new optparser ~version:"1.0" () and verboseness = ref 0 and title = (StdOpt.int_option ~metavar:"NUM" ~default:1 ()) and vol_id = (StdOpt.str_option ~metavar:"TITLE" ~default:"DEFLABEL" ()) and super_seekrit = (StdOpt.store_true ()) in (do { op#add ~help:"Increase verboseness; this help message is extra long just to see if wrapped lines work properly when the corresponding options overflow the 'option area'." ["-v";"--verbose";"--talkative"] (StdOpt.count_option ~increment:1 verboseness); op#add ~help:"Decrease verboseness" ["-q"; "--quiet"] (StdOpt.count_option ~increment:(-1) verboseness); op#add ~help:"Select title # to keep" ["-T"; "--title"] title; op#add ~help:"set the Volume ID (label) of the file system" ["-V"] vol_id; op#add ~help:"set the super-seekrit option" ~show:False ["-S"] super_seekrit; op#add ~help:"set a random string option to something, by the way this is a very long help text, but then that's OK. It will just get wrapped neatly." ["-X"] some_string; printf "verboseness: %d\n" verboseness.val; printf "title: %d\n" (Opt.get title); printf "vol_id: %s\n" (Opt.get vol_id); printf "super-seekrit: %b\n" (Opt.get super_seekrit); flush stdout; }) When run with the --help option (which is automatically added unless explicitly suppressed), it produces the following output: usage: sample1 [options] options: --version show program's version and exit -h, --help show this help message and exit -v, --talkative, --verbose Increase verboseness; this help message is extra long just to see if wrapped lines work properly when the corresponding options overflow the 'option area'. -q, --quiet Decrease verboseness -TNUM, --title=NUM Select title # to keep -VTITLE set the Volume ID (label) of the file system -XSTR set a random string option to something, by the way this is a very long help text, but then that's OK. It will just get wrapped neatly. (output is currently always formatted for a terminal width of 79; I'll see if we can't get the terminal width from some built-in library...) There are a couple of issues of style with _using_ the code: - An earlier version used labeled arguments ~short_name, ~short_names, ~long_name, ~long_names to construct the option strings. As an example, here's what the "quiet" declaration above would look like: op#add ~help:"Decrease verboseness" ~short_name:'q' ~long_name:"quiet" (StdOpt.count_option ~increment:(-1) verboseness); This just seems cleaner to me (and is very slightly more type safe), but I thought I'd ask you all for opinions on that. - I feel it's quite ugly to use names like "int_option" and "str_option", but the only alternative I can see (if we want polymorphism and type safety) is: Get rid of "int_option", et.al. and have just one value_option which (as its only required parameter) a a module with a signature that includes an "of_string" function. This would look like: let int_opt1 = value_option ... Integer in ... which just looks cleaner to me (and obviates the need for a separate module namespace for xxx_option functions to avoid polluting the namespace too much). There are practical problems, though: Almost no relevant modules actually have an "of_string", there is no Integer module, etc. One semi-serious problem with relying on these "built-in" conversion is that the "Failure _" exceptions they raise have values which are useless for displaying to the user, so one must either accept a generic "could not read value '$ARG'" message, or just accept the useless messages from the built-in functions. I'm not too familiar with modules, so it may be possible to wrap the standard modules using something similar to how ExtString does it and provide more useful exception messages... Ideas, anyone? There are also a couple of implementation issues which I'd like to get general consensus on: - Option groups: Should they be supported? See http://www.python.org/doc/current/lib/optparse-generating-help.html for an example of how that would look (output-wise). AFAIK, they serve only cosmetic purposes in optparse.py. - Formatting: Should the interface to the help text formatter be exposed to the user? (This would require exporting a bit more of the internals, but would probably not be _too_ bad). Sooo... what you think? A serious contenter for Arg/Getopt for (eventual) inclusion in ExtLib? Any and all constructive criticism would be greatly appreciated! :) -- Bardur Arantsson <ba...@im...> <ba...@sc...> - Head of Safety? Five buttons? I'm in! Arnold Rimmer | Red Dwarf |
From: Falk H. <hue...@in...> - 2004-08-13 19:18:13
|
Bardur Arantsson <oca...@sc...> writes: > As promised, here's my take on how option parsing should > be done (i.e. Python optparse-style). > [...] > let op = > new optparser ~version:"1.0" () Is there a reason optparser is a class? I don't see any, but then I've never used classes at all, so maybe I'm missing something... > (output is currently always formatted for a terminal width of 79; > I'll see if we can't get the terminal width from some built-in > library...) You can check for "COLUMNS" in the environment. -- Falk |
From: Bardur A. <oca...@sc...> - 2004-08-13 19:47:18
|
On Fri, Aug 13, 2004 at 09:17:57PM +0200, Falk Hueffner wrote: > Bardur Arantsson <oca...@sc...> writes: > > > As promised, here's my take on how option parsing should > > be done (i.e. Python optparse-style). > > [...] > > let op = > > new optparser ~version:"1.0" () > > Is there a reason optparser is a class? I don't see any, but then I've > never used classes at all, so maybe I'm missing something... There isn't any technical reason it couldn't be an opaque record type (it's not meant to be subclassed or anything like that), but then there isn't any great advantage to that either. I just think that the actual _usage_ is slightly nicer -- Contrast Opt.add ... (int_option ...) op; with just op#add ... (int_option ...); I guess I've just always felt that there is some "redundancy" in the first form. > > > (output is currently always formatted for a terminal width of 79; > > I'll see if we can't get the terminal width from some built-in > > library...) > > You can check for "COLUMNS" in the environment. I was hoping that there'd be some sort of way of using something like the terminal functions of the Unix module, but I guess using COLUMNS should work in most Unix-like environments. I'll add a bit of code to do that. -- Bardur Arantsson <ba...@im...> <ba...@sc...> The sudden appearance of a naked woman always caused a rethink of anyone's immediate plans. Terry Pratchett | Jingo |
From: Bardur A. <oca...@sc...> - 2004-08-13 20:03:30
|
On Fri, Aug 13, 2004 at 09:47:13PM +0200, Bardur Arantsson wrote: > > > (output is currently always formatted for a terminal width of 79; > > > I'll see if we can't get the terminal width from some built-in > > > library...) > > > > You can check for "COLUMNS" in the environment. > > I was hoping that there'd be some sort of way of using > something like the terminal functions of the Unix module, > but I guess using COLUMNS should work in most Unix-like > environments. > > I'll add a bit of code to do that. Hmmm... It seems that $COLUMNS isn't normally exported by the shell; neither bash nor zsh do it. I've added code to check for it (just in case), but the user must still explicitly export $COLUMNS for it to work. -- Bardur Arantsson <ba...@im...> <ba...@sc...> - Morbo congratulates our gargantuan cyborg president. May death come quickly to his enemies. Morbo | Futurama |
From: Falk H. <hue...@in...> - 2004-08-13 21:00:52
|
Bardur Arantsson <oca...@sc...> writes: > On Fri, Aug 13, 2004 at 09:17:57PM +0200, Falk Hueffner wrote: >> Is there a reason optparser is a class? I don't see any, but then I've >> never used classes at all, so maybe I'm missing something... > > There isn't any technical reason it couldn't be an opaque > record type (it's not meant to be subclassed or anything > like that), but then there isn't any great advantage to > that either. I just think that the actual _usage_ is > slightly nicer -- Contrast > > Opt.add ... (int_option ...) op; > > with just > > op#add ... (int_option ...); > > I guess I've just always felt that there is some "redundancy" in the > first form. But it's more idiomatic. IMHO one shouldn't use classes unless one actually intends to use their features like overriding. It's also less efficient, although of course that hardly matters here. But I guess it's just a matter of taste. -- Falk |
From: Nicolas C. <war...@fr...> - 2004-08-13 21:35:10
|
> > On Fri, Aug 13, 2004 at 09:17:57PM +0200, Falk Hueffner wrote: > >> Is there a reason optparser is a class? I don't see any, but then I've > >> never used classes at all, so maybe I'm missing something... > > > > There isn't any technical reason it couldn't be an opaque > > record type (it's not meant to be subclassed or anything > > like that), but then there isn't any great advantage to > > that either. I just think that the actual _usage_ is > > slightly nicer -- Contrast > > > > Opt.add ... (int_option ...) op; > > > > with just > > > > op#add ... (int_option ...); > > > > I guess I've just always felt that there is some "redundancy" in the > > first form. > > But it's more idiomatic. IMHO one shouldn't use classes unless one > actually intends to use their features like overriding. It's also less > efficient, although of course that hardly matters here. But I guess > it's just a matter of taste. More important is that objects are not that much "core" OCaml (whatever the O'). They are well supported by the INRIA team of course, but almost no code in the ocaml sources uses objects, and no special support is done for them. Class typing is actually a big mess in the compiler and might be quite difficult to improve further, and then break at next language evolution. The module system is mature and better handled by the compiler (especially concerning error messages that tends to be oververbose when using objects) so it should be the default choice we implementing some library. However there is some design choices were objects particulary fit, but I don't think the GetOpt is one of these (didn't look at the sources yet, might do this weekend, thanks for the contribution anyway). Regards, Nicolas Cannasse |
From: Bardur A. <oca...@sc...> - 2004-08-13 21:43:24
|
On Fri, Aug 13, 2004 at 11:35:36PM +0200, Nicolas Cannasse wrote: > > > On Fri, Aug 13, 2004 at 09:17:57PM +0200, Falk Hueffner wrote: > > >> Is there a reason optparser is a class? I don't see any, but then I've > > >> never used classes at all, so maybe I'm missing something... > > > > > > There isn't any technical reason it couldn't be an opaque > > > record type (it's not meant to be subclassed or anything > > > like that), but then there isn't any great advantage to > > > that either. I just think that the actual _usage_ is > > > slightly nicer -- Contrast > > > > > > Opt.add ... (int_option ...) op; > > > > > > with just > > > > > > op#add ... (int_option ...); > > > > > > I guess I've just always felt that there is some "redundancy" in the > > > first form. > > > > But it's more idiomatic. IMHO one shouldn't use classes unless one > > actually intends to use their features like overriding. It's also less > > efficient, although of course that hardly matters here. But I guess > > it's just a matter of taste. > > More important is that objects are not that much "core" OCaml (whatever the > O'). They are well supported by the INRIA team of course, but almost no code > in the ocaml sources uses objects, and no special support is done for them. > Class typing is actually a big mess in the compiler and might be quite > difficult to improve further, and then break at next language evolution. The > module system is mature and better handled by the compiler (especially > concerning error messages that tends to be oververbose when using objects) > so it should be the default choice we implementing some library. However > there is some design choices were objects particulary fit, but I don't think > the GetOpt is one of these (didn't look at the sources yet, might do this > weekend, thanks for the contribution anyway). If that's the way people generally feel about objects then I'll be quite happy to change it. (However, there is still the question of whether we want to allow custom formatters. If that's the case, then inheritance _will_ probably be an issue for those, and they'll be objects). -- Bardur Arantsson <ba...@im...> <ba...@sc...> - Keaton once said, "I don't believe in God, but I'm afraid of him". Well, I believe in God, and the only thing that scares me is Kayser Soze. Verbal Kint | The Usual Suspects |
From: Markus M. <ma...@oe...> - 2004-08-13 22:32:32
|
On Fri, 13 Aug 2004, Bardur Arantsson wrote: > If that's the way people generally feel about objects then > I'll be quite happy to change it. Yes, please :-) > (However, there is still the question of whether we want > to allow custom formatters. If that's the case, then > inheritance _will_ probably be an issue for those, and > they'll be objects). No, you can also use modules to a great extent here. Just use functors for providing custom formatters. Regards, Markus -- Markus Mottl http://www.oefai.at/~markus ma...@oe... |
From: Nicolas C. <war...@fr...> - 2004-08-14 07:54:45
|
> > If that's the way people generally feel about objects then > > I'll be quite happy to change it. > > Yes, please :-) > > > (However, there is still the question of whether we want > > to allow custom formatters. If that's the case, then > > inheritance _will_ probably be an issue for those, and > > they'll be objects). > > No, you can also use modules to a great extent here. Just use functors > for providing custom formatters. > > Regards, > Markus I'ld prefer not to get custom formatters right now, if that means avoiding the usage of functors - especially when mixed with recursive modules. They're nice and powerful constructors, but the end-user which is not familiar which such things might have trouble figuring out what the library is exactly doing :) Regards, Nicolas |
From: Bardur A. <oca...@sc...> - 2004-08-14 08:06:40
|
On Sat, Aug 14, 2004 at 09:54:59AM +0200, Nicolas Cannasse wrote: > > > If that's the way people generally feel about objects then > > > I'll be quite happy to change it. > > > > Yes, please :-) > > > > > (However, there is still the question of whether we want > > > to allow custom formatters. If that's the case, then > > > inheritance _will_ probably be an issue for those, and > > > they'll be objects). > > > > No, you can also use modules to a great extent here. Just use functors > > for providing custom formatters. > > > > Regards, > > Markus > > I'ld prefer not to get custom formatters right now, if that means avoiding > the usage of functors - especially when mixed with recursive modules. > They're nice and powerful constructors, but the end-user which is not > familiar which such things might have trouble figuring out what the library > is exactly doing :) I've already started changing the formatters to functors, so I might as well finish. :) I guess we could just provide an OptParser module which uses the "default" formatter automatically and provide "another" OptParserWithFormatter module which takes a Formatter "parameter". Any objection to that? -- Bardur Arantsson <ba...@im...> <ba...@sc...> - PC Load Letter? What the F*** does that mean? Michael Bolton | Office Space |
From: Markus M. <ma...@oe...> - 2004-08-14 08:13:59
|
On Sat, 14 Aug 2004, Bardur Arantsson wrote: > I guess we could just provide an OptParser module which > uses the "default" formatter automatically and provide > "another" OptParserWithFormatter module which takes a > Formatter "parameter". > > Any objection to that? No, that was exactly what I had in mind. Regards, Markus -- Markus Mottl http://www.oefai.at/~markus ma...@oe... |
From: Bardur A. <oca...@sc...> - 2004-08-14 08:31:44
|
On Sat, Aug 14, 2004 at 10:13:48AM +0200, Markus Mottl wrote: > On Sat, 14 Aug 2004, Bardur Arantsson wrote: > > I guess we could just provide an OptParser module which > > uses the "default" formatter automatically and provide > > "another" OptParserWithFormatter module which takes a > > Formatter "parameter". > > > > Any objection to that? > > No, that was exactly what I had in mind. I thought so :). I've now finished the functorization itself, but for the life of me I can't find the proper syntax/whatever to declare the "defaulted" OptParser module. Maybe someone can shed some light on this: I'm using the following declarations in the .mli file: module type Formatter = sig val hello_world : unit -> unit end module StdFormatter : Formatter module OptParserWithFormatter (F:Formatter) : sig val say : unit -> unit (** This may call F.hello_world at some point... *) end what I want now is to declare the "default" OptParser as an OptParserWithFormatter with F=StdFormatter. I've tried various things, but OCaml just keeps telling me that "OptParserWithFormatter" is unbound...? -- Bardur Arantsson <ba...@im...> <ba...@sc...> - BART! Stop pestering Satan! Marge Simpson | The Simpsons |
From: Falk H. <hue...@in...> - 2004-08-14 08:33:53
|
Bardur Arantsson <oca...@sc...> writes: > I guess we could just provide an OptParser module which uses the > "default" formatter automatically and provide "another" > OptParserWithFormatter module which takes a Formatter "parameter". Why not just have a set_formatter function which overrides the default formatter? -- Falk |
From: Nicolas C. <war...@fr...> - 2004-08-14 08:47:24
|
> Bardur Arantsson <oca...@sc...> writes: > > > I guess we could just provide an OptParser module which uses the > > "default" formatter automatically and provide "another" > > OptParserWithFormatter module which takes a Formatter "parameter". > > Why not just have a set_formatter function which overrides the default > formatter? I also think that a more light approach is better. We're not dealing with a big framework where we need to inherit a lot of code. As Bardur said before, what we need is a general usage that will satisfy 99% of the users. Providing functionalities such as custom formatters for the remaining 1% is nice, but should be almost invisible from the average user. Using functors is not the most light way from doing, simply let them pass a custom formatter lambda function and you well get a more simple implementation with lighter user interface. Nicolas Cannasse |
From: Bardur A. <oca...@sc...> - 2004-08-14 08:57:16
|
On Sat, Aug 14, 2004 at 10:47:51AM +0200, Nicolas Cannasse wrote: > > Bardur Arantsson <oca...@sc...> writes: > > > > > I guess we could just provide an OptParser module which uses the > > > "default" formatter automatically and provide "another" > > > OptParserWithFormatter module which takes a Formatter "parameter". > > > > Why not just have a set_formatter function which overrides the default > > formatter? > > I also think that a more light approach is better. > We're not dealing with a big framework where we need to inherit a lot of > code. As Bardur said before, what we need is a general usage that will > satisfy 99% of the users. Providing functionalities such as custom > formatters for the remaining 1% is nice, but should be almost invisible from > the average user. Using functors is not the most light way from doing, > simply let them pass a custom formatter lambda function and you well get a > more simple implementation with lighter user interface. > For the casual user the interface will be the *exactly* the same, they'll never even notice that functors are being used. The reason I'm didn't want to use closures for formatters is that the formatters aren't just one big "here's all the option metadata, now give me a nicely formatted string" function. You can do quite meaningful reuse of code, for instance, one can trivially provide one standard formatter which looks like this usage: sample1 [options] options: --version show program's version and exit -h, --help show this help message and exit -v, --talkative, --verbose Increase verboseness; this help message is extra long just to see if wrapped lines work properly when the corresponding options overflow the 'option area'. -q, --quiet Decrease verboseness and another standard formatter which looks like this Usage: ====== sample1 [options] Options: ======== --version show program's version and exit -h, --help show this help message and exit -v, --talkative, --verbose Increase verboseness; this help message is extra long just to see if wrapped lines work properly when the corresponding options overflow the 'option area'. -q, --quiet Decrease verboseness The code is almost exactly the same, but using modules allows easy and clean reuse without having to expose various "internal" functions. -- Bardur Arantsson <ba...@im...> <ba...@sc...> - Power corrupts. Absolute power is kind of neat. John Lehman, Secretary of the US Navy 1981-1987 |
From: Nicolas C. <war...@fr...> - 2004-08-14 09:20:12
|
> The code is almost exactly the same, but using modules > allows easy and clean reuse without having to expose > various "internal" functions. Why not exposes them actually ? ( in a separate section of the MLI so they don't cripple the documentation). That's somehow what you're doing when using fonctors, isn't it ? Regards, Nicolas Cannasse |
From: Bardur A. <oca...@sc...> - 2004-08-14 10:12:32
|
On Sat, Aug 14, 2004 at 11:20:36AM +0200, Nicolas Cannasse wrote: > > The code is almost exactly the same, but using modules > > allows easy and clean reuse without having to expose > > various "internal" functions. > > Why not exposes them actually ? > ( in a separate section of the MLI so they don't cripple the documentation). > That's somehow what you're doing when using fonctors, isn't it ? Currently, the formatter interface is like this: module type Formatter = ( sig type t = 'a; value make_default : unit -> t; value indent : t -> unit; value dedent : t -> unit; value format_usage : t -> string -> string; value format_heading : t -> string -> string; value format_description : t -> string -> string; value format_option : t -> ... -> string; end) module StdFormatter = (struct type t = { ... }; value make option1 option2 ... = ...; ... end) with StdFormatter implementing all the methods to provide the current form of output (I'll probably add another one with slightly different heading/usage formatting, but that's another matter). Am I correct in thinking that you would instead want something like this: module Formatter : (struct type t = { indent : unit -> t; dedent : unit -> t; format_usage : t -> string -> string; format_heading : t -> string -> string; format_description : t -> string -> string; format_option : t -> ... -> string; }; val make_std_formatter ... val make_whatever_formatter ... ); where the "user" is then able to override a e.g. format_usage by saying module MyFormatter = (struct open Formatter; val make_my_formatter ... = { make_std_formatter ... with format_usage = (fun ...) }; end and then using MyFormatter.make_my_formatter ... instead of Formatter.make_std_formatter? Technically speaking I suppose there isn't *that* much difference, but the functor approach just "feels" cleaner to me. -- Bardur Arantsson <ba...@im...> <ba...@sc...> - Verbing weirds language. Calvin | Calvin & Hobbes |
From: Bardur A. <oca...@sc...> - 2004-08-14 10:16:47
|
On Sat, Aug 14, 2004 at 12:12:21PM +0200, Bardur Arantsson wrote: > On Sat, Aug 14, 2004 at 11:20:36AM +0200, Nicolas Cannasse wrote: > > > > The code is almost exactly the same, but using modules > > > allows easy and clean reuse without having to expose > > > various "internal" functions. > > > > Why not exposes them actually ? > > ( in a separate section of the MLI so they don't cripple the documentation). > > That's somehow what you're doing when using fonctors, isn't it ? > [--snip--] Forgot to add: If it'll improve the chances of getting OptParse into ExtLib, I'll gladly change to using "simple" modules and a record type containing closures. :) There isn't enough of a technical difference to make it worth squabbling over. :) -- Bardur Arantsson <ba...@im...> <ba...@sc...> What is it with this genre thing? I don't like musical genres, I like music that I like. patternjuggler | http://slashdot.org |
From: Bardur A. <oca...@sc...> - 2004-08-13 23:03:17
|
On Sat, Aug 14, 2004 at 12:32:19AM +0200, Markus Mottl wrote: > On Fri, 13 Aug 2004, Bardur Arantsson wrote: > > If that's the way people generally feel about objects then > > I'll be quite happy to change it. > > Yes, please :-) > Your wish is my command ;). I'll change the interface accordingly and put a new version up tomorrow. > > (However, there is still the question of whether we want > > to allow custom formatters. If that's the case, then > > inheritance _will_ probably be an issue for those, and > > they'll be objects). > > No, you can also use modules to a great extent here. Just use functors > for providing custom formatters. > I'll look into it, but I was under the impression that you cannot inherit implementation (which is quite important for formatters) between modules...? -- Bardur Arantsson <ba...@im...> <ba...@sc...> It hovered above the ground, much in the way that bricks don't. Douglas Adams | Hitchiker's Guide to the Galaxy |
From: Markus M. <ma...@oe...> - 2004-08-13 23:13:19
|
On Sat, 14 Aug 2004, Bardur Arantsson wrote: > I'll look into it, but I was under the impression that you > cannot inherit implementation (which is quite important > for formatters) between modules...? Sure you can: module Foo = struct ... end module Bar = struct include Foo end In extreme cases (though that's very seldom) you could even supply 2nd-order functors: you pass the argument of your module another module. The result of this application can then e.g. be included again in another module, etc. You can almost always avoid objects. With recursive modules you can even get open recursion working for you. Using clever tricks even across file boundaries: just functorize the two modules, which should be mutually recursive, and tie the recursive knot elsewhere. Regards, Markus -- Markus Mottl http://www.oefai.at/~markus ma...@oe... |
From: skaller <sk...@us...> - 2004-08-13 23:23:04
|
On Sat, 2004-08-14 at 09:03, Bardur Arantsson wrote: > I'll look into it, but I was under the impression that you > cannot inherit implementation (which is quite important > for formatters) between modules...? Look for 'include' directive. -- John Skaller, mailto:sk...@us... voice: 061-2-9660-0850, snail: PO BOX 401 Glebe NSW 2037 Australia Checkout the Felix programming language http://felix.sf.net |
From: skaller <sk...@us...> - 2004-08-13 22:10:03
|
On Sat, 2004-08-14 at 05:47, Bardur Arantsson wrote: > On Fri, Aug 13, 2004 at 09:17:57PM +0200, Falk Hueffner wrote: > > > Bardur Arantsson <oca...@sc...> writes: > > > > > As promised, here's my take on how option parsing should > > > be done (i.e. Python optparse-style). > > > [...] > > > let op = > > > new optparser ~version:"1.0" () > > > > Is there a reason optparser is a class? I don't see any, but then I've > > never used classes at all, so maybe I'm missing something... > > There isn't any technical reason it couldn't be an opaque > record type (it's not meant to be subclassed or anything > like that), However -- you should consider that. Option parsing is something that clients are likely to need to mess with, and some flexibility may well be obtained by allowing some of the methods or representation to be replaced. > I was hoping that there'd be some sort of way of using > something like the terminal functions of the Unix module, > but I guess using COLUMNS should work in most Unix-like > environments. No, stuff the columns idea completely. Print the help out as the user put the text in. Don't even *try* to format it. Let the client do it, and let *them* worry about columns. If you want to pretty print -- you need a proper pretty printer, and that isn't the job this module has taken on. -- John Skaller, mailto:sk...@us... voice: 061-2-9660-0850, snail: PO BOX 401 Glebe NSW 2037 Australia Checkout the Felix programming language http://felix.sf.net |
From: Bardur A. <oca...@sc...> - 2004-08-13 22:19:39
|
On Sat, Aug 14, 2004 at 08:09:56AM +1000, skaller wrote: > On Sat, 2004-08-14 at 05:47, Bardur Arantsson wrote: > > On Fri, Aug 13, 2004 at 09:17:57PM +0200, Falk Hueffner wrote: > > > > > Bardur Arantsson <oca...@sc...> writes: > > > > > > > As promised, here's my take on how option parsing should > > > > be done (i.e. Python optparse-style). > > > > [...] > > > > let op = > > > > new optparser ~version:"1.0" () > > > > > > Is there a reason optparser is a class? I don't see any, but then I've > > > never used classes at all, so maybe I'm missing something... > > > > There isn't any technical reason it couldn't be an opaque > > record type (it's not meant to be subclassed or anything > > like that), > > However -- you should consider that. Option parsing > is something that clients are likely to need to > mess with, and some flexibility may well be > obtained by allowing some of the methods or representation > to be replaced. Nope, no part of the option parser would ever need to be replaced/overridden -- everything that warrants customization can already be customized through the rest of the interface. That's kind of the whole point. > > > I was hoping that there'd be some sort of way of using > > something like the terminal functions of the Unix module, > > but I guess using COLUMNS should work in most Unix-like > > environments. > > No, stuff the columns idea completely. > Print the help out as the user put the text in. > Don't even *try* to format it. Let the client > do it, and let *them* worry about columns. No, this is more work for the user of the API. All of this results in lots of duplicated, half-working code, precisely the thing we want to avoid. > > If you want to pretty print -- you need a proper > pretty printer No you don't, actually. You only need a very specialized type of pretty printer (which is already written and works very well thankyouverymuch :)). > and that isn't the job this module has taken on. Yes it is -- remember the idea is: Option parsing should work as expected (by default), but you _can_ override behavior which it makes sense to override. I suggested exposing the formatting interface so that if someone doesn't like the default formatting, then they can override the default formatting and provide their own. -- Bardur Arantsson <ba...@im...> <ba...@sc...> If at first you don't succeed, failure may be your style. http://www.demotivators.com |
From: skaller <sk...@us...> - 2004-08-13 22:47:40
|
On Sat, 2004-08-14 at 08:19, Bardur Arantsson wrote: > Nope, no part of the option parser would ever need to be > replaced/overridden -- everything that warrants > customization can already be customized through the rest > of the interface. LOL! Just wait until you try it on real users :) Like people that would like to use your module to extend their *existing* option parsing scheme. If you think you've thought of everything -- you got another think coming :) -- John Skaller, mailto:sk...@us... voice: 061-2-9660-0850, snail: PO BOX 401 Glebe NSW 2037 Australia Checkout the Felix programming language http://felix.sf.net |
From: Bardur A. <oca...@sc...> - 2004-08-13 23:01:11
|
On Sat, Aug 14, 2004 at 08:47:35AM +1000, skaller wrote: > On Sat, 2004-08-14 at 08:19, Bardur Arantsson wrote: > > > Nope, no part of the option parser would ever need to be > > replaced/overridden -- everything that warrants > > customization can already be customized through the rest > > of the interface. > > LOL! Just wait until you try it on real users :) > Like people that would like to use your module > to extend their *existing* option parsing scheme. Heh, the key word is _reasonable_ (should have put that in there, I'm sure I put it somewhere in that mail :)). But, sure... If you, for instance, don't want getopt-style options (or something as radical as that), then you're not going to get anything out of the module. Then you might as well just implement your own option parsing because you're going to working "against" the spirit of the OptParse module anyway. Remember: I'm NOT trying to create something which will handle *any* situation, I'm trying to create something which will handle any *reasonable* situation with a minimum amount of fuss. Something which 99.9% of developers can just use out-of-the-box without any need for customization. > If you think you've thought of everything -- you got > another think coming :) That's why I asked for comments. :) Collectively we _might_ be able to think of everything within reason -- i.e. all the options/possibilities which those 99.9% of users might find a use for. -- Bardur Arantsson <ba...@im...> <ba...@sc...> Anyone who is capable of getting themselves made President should on no account be allowed to do the job. Douglas Adams | Hitchiker's Guide to the Galaxy |