From: Natasha Kerensikova <lithiumcat@gmail.com>
Subject: Re: Starter project: getopt_long in Ada
Date: Sat, 26 Nov 2011 18:13:22 +0000 (UTC)
Date: 2011-11-26T18:13:22+00:00 [thread overview]
Message-ID: <slrnjd2b1q.vl6.lithiumcat@sigil.instinctive.eu> (raw)
In-Reply-To: 4ecfc4c4$0$6579$9b4e6d93@newsspool3.arcor-online.net
Hello,
On 2011-11-25, Georg Bauhaus <rm.dash-bauhaus@futureapps.de> wrote:
> I'd prefer these handlers to be "linguistically" collected in
> one place (and a different sets of handlers collected in
> different places, respectively).
I completely agree that the error handler are indeed connected. I'm
still genuinely wondering whether they should be grouped with the
argument callback like you suggest or not.
> In order to achieve this,
> an abstract type can state the list of handling procedures,
> with null defaults for operations the programmer does not
> wish to do anything special.
You seem to be missing one important point about these handlers,
probably because it's not documented well enough: the error callbacks
are currently defaulting to null, but that null does not mean nothing is
performed when such an error is encountered (i.e. a null procedure), it
means that an Option_Error exception is raised.
In most use cases I can imagine, an application encountering an error in
argument parsing will just print a "usage" text and exit with an error
code, that can be done simply by catching Natools.Getopt_Long.Option_Error
exception.
However some tools not only print the generic "usage" text, they also
print what was wrong in the given arguments. Some tools even do so in a
runtime-selected language (e.g. locale facilities), which prevents using
blindly the exception message. That's how I came up with the callbacks,
which allows to communicate what went wrong (and then the ability to
recover from such errors was a happy side-effect I decided to keep; but
I have never encountered any command-line tool that does recover from
command-line argument errors).
That's why I'm wondering (and implicitly asking your opinion) whether
the "normal" callback should be bundled with the error handling
callbacks.
All applications will have to provide a useful callback for argument
processing, even when they don't do any error handling beyond printing
"usage" text and aborting. So maybe it would make sense to keep the
access-to-procedure Callback argument, and create an
Option_Error_Handler class, whose default value in Process would be
something that just raises Option_Error (which would by the way make
Process body cleaner by not having to check null access).
On the other hand, I could also go for an Option_Handler abstract class,
with abstract regular Callback and with overrideable implementations for
error handlers that raise Option_Error.
> Defining this type has the
> advantages that it makes programmers write software organized
> into typed structure, yielding
>
> 1) definite places to look for the handling procedures
> 2) handlers that can share common data for communicating
> parsing state among them
> 3) human readers that know about 1 and 2 because they can
> look for concrete types derived from the abstract type.
While I certainly agree with this in general, in this particular case
I'm skeptical about (2), since I can't think of any example where error
handlers are not fatal, which leaves only one handler that only has to
communicate with itself.
The error handlers are really only a workaround to have in effect
exceptions with structured arguments.
> I think the advantages outweigh a minor loss in flexibility,
> if you'd want to call flexibility the ability to pass a
> collection of subprograms each declared just anywhere.
Yes, I'm completely sold on the idea of using a dispatching call instead
of error handler accesses. And still unsure about the normal handler.
> Influencing the shape of this type, Process's parameters
> such as Posixly_Correct might mean that the handling
> procedures may want to determine whether or not Posixly_Correct
> is true.
I think it depends on who is supposed to set these parameters. For
example Long_Only should not be changed while Process is running, so I
don't like it being a record component or the result of a function.
Having it a type discriminant like you suggest feels like an abuse of
the type discriminant feature, but I cannot manage to tell why (and I
might be wrong, considering I'm still too new to have accurate
feelings).
Posixly_Correct could be changed on-the-fly (even though in the C code I
took inspiration from it was a compile-time option), even though I don't
see any reason to do so (a meta-flag?).
I will give it some deeper thought.
> So, then, my first idea will be along these lines:
>
> package Natools.Handlers is
>
> type Id_And_Argument_Handler
> (Posixly_Correct : Boolean;
> ...)
> is abstract tagged private;
>
> procedure Callback
> (Handler : in out Id_And_Argument_Handler;
> Id : Option_Id;
> Argument : String) is abstract;
>
> procedure Missing_Argument
> (Handler : in out Id_And_Argument_Handler;
> Id : Option_Id) is null;
>
> etc.
>
> end Natools.Handlers;
I'm afraid it will not work, since Option_Id is a formal type from
generic package Natools.Getopt_Long.
However, is there anything wrong with having something like the
following?
generic
type Option_Id is (<>);
package Natools.Getopt_Long is
Option_Error : exception;
package Handlers is
type Argument_Handler is abstract tagged null record;
procedure Missing_Argument
(Handler : in out Argument_Handler;
Id : Option_Id); -- implementation raises Option_Error;
-- others handlers, maybe including regular argument callback
end Handlers;
procedure Process ( -- arguments to be written later
end Natools.Getopt_Long;
Or is the inner package looking for trouble?
> I did not look at the implementation.
I'm sure there are very useful lessons for me to draw from the
implementation. Still I'm very grateful for your comments on the
specification, I think that's the best way for me to make progress at
this point.
Thanks a lot for your help,
Natasha
next prev parent reply other threads:[~2011-11-26 18:13 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-11-25 10:47 Starter project: getopt_long in Ada Natasha Kerensikova
2011-11-25 16:39 ` Georg Bauhaus
2011-11-26 18:13 ` Natasha Kerensikova [this message]
2011-11-26 20:47 ` Jeffrey Carter
2011-11-28 15:49 ` Georg Bauhaus
2011-11-28 17:18 ` Natasha Kerensikova
2011-11-27 8:21 ` Yannick Duchêne (Hibou57)
2011-11-27 12:30 ` Natasha Kerensikova
2011-11-27 15:11 ` Yannick Duchêne (Hibou57)
2011-11-28 8:21 ` Natasha Kerensikova
2011-11-28 13:02 ` Yannick Duchêne (Hibou57)
2011-11-27 8:05 ` Yannick Duchêne (Hibou57)
2011-11-27 12:39 ` Natasha Kerensikova
2011-11-27 14:52 ` Yannick Duchêne (Hibou57)
2011-11-27 8:09 ` Yannick Duchêne (Hibou57)
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox