Boost logo

Boost :

From: Vladimir Prus (ghost_at_[hidden])
Date: 2003-05-28 01:09:03


Rozental, Gennadiy wrote:

> 1. You store something inside class cmdline

Actually, only arguments, for the benefit of folks which might use 'cmdline'
standalone. Options are not stored there.

> 2. You store strings in options_and_arguments
> 3. You store typed values in variables_map
>
> In my opinion 2 places are redundant. You should only have one.

OK, I understand your opinion. I'm probably misusing "you don't pay for what
you don't use" principle, but I find that 'options_and_argument' class is
important. Sometimes you really don't need typed storage.

>> > Plus second layer managing composition of parameter originated by
>> > different sources.
>
>> That's 'variables_map'.
>
> But variables map is part of first layer, it's store typed arguments. And
> it almost
> does not have any functionality I expect to see on this second layer
> dedicated to combinind parameters from different sources.

It's possible to link several variables_map instances in a chain, which
handles the primary need: different preference of options from different
sources. It's true that different naming of options is not handled, however
I'm still considering if it's better to do that in parsers.

>> >> > b. Force same style for all parameters in command line (I could
>>not
>>>> > define /h --my_long_param)
>>>>
>>>> Do you need it in practice?
>>>
>>> Why not. Maybe different modules require parameters in different
>>style.
>>
>>I feel this to be artifical example, and would not be surprised if no
>>user
>>of program_options will ever want it. And if it wants... custom parsers
>>can be used.
>
> But this is part of functionaly you supply out of the box. And now i need
> ot rewrite it.
> You keep repeating: "use custom parser". I wonder why would I need this
> framework then.

1. I think that less than 1% of users would ever need it. In that case,
there's nothing wrong with asking that 1% to put some effort for their
special needs.

2. BTW, you've said that I can't have "/h --my_long_param" and I've started
to argue that this style is rare and custom parser can help. But really,
that style *is* supported. There no "unix" style and "windows" style, but
rather a set of possible syntaxes. So, (cmdline::unix_style |
cmdline::allow_slash_for_short) enables the syntax you want.

> In my terms above would look like this:
>
> parameter<std::string>( "output" )
> << place_to( output_file_name )
> << default_value( "/tmp/abc" )
> << description( "output file name" )
>
> You do not need to know anything in addition about how parser works.
> Moreover it's unifies and easily extendable to adopt different modifers.

It seems we'll make no progress with this question. I find your syntax more
verbose, and it still leaves questions. What if I have "--output foo
--output bar" or when does default value plays: can I write simply
"--output", without any value?

>>With iterators, that would become
>>
>> for(cmdline_iterator i(...), e; i != e; ++i) {
>> if (i->is_option()) {
>>
>>
>>Wait! Again, what's 'value_type'. Some imaginary 'option_or_argument'
>>class?
>>boost::variant? boost::any? Yep, that would be an interator, but you
>>gain
>>nothing. It will be only input iterator, and with such a specialized
>>'value_type', that to use that iterator, you need to known that you're
>>dealing with command line --- there's no place for genericity.

> In my design I provide rnadom access iterator to the storage of parsed
> arguments of
> type cla::argument. And I could use whatever generic algorithm I like with
> it.

Let's then postpone this question until your library is reviwed. I found
that 'argument's interface is too lean to make any use of it, but if that's
really so if not question about my library.

> Why does anybody need raw_option_name()?

In short, this supports scenario where you define a group of options as
valid, using "*" symbol

   desc.add_options()
        ("diff_option.*", "", "")

This would allow your program to accept everyting starting with
"diff_option.". In this case, you really don't want to list all options of
'diff' as supported. It seems that multi-pass parsing won't help here.

 
> Also it's beyond my understanding why we need at_option, at_argument. May
> be it's because I still could not get what meaning you use for these terms
> in this context.
> I parsed argc/argv, stored typed argument. Now I only need ot get the
> value
> out of argument I identifued somehow (by name, or index, or order -
> whatever)

You don't need 'at_option'/'at_argument' because you parse either all
options or all arguments. When you parse them at the same time, your really
have to know that's next on command line.

>>> > 9. Multi-pass parsing support
>> If that's not sufficient (which I doubt), I can think of a more general
>> solution. Basically, 'cmdline' class can allow unregistered options.
>> With
>> a bit of tweaking, it can return unparsed tokens.
>
> There is a solution. But it's not trivial. And not in a bound ot your
> current design.

We'll see...

>> I don't see here handling of response files or config files... if you
>> were
>> to add it, would you write the same "if" block a couple of times?
>
> I may have several if spatements:
> if( cla_parser.parse(...) ) ...
> if( config_file.parse(...) ) ...
> ...
>
> It's not worse than several catch clauses. Try/catch seems redundant when
> used right aroung the function that throw an exception.

But it's worse than *one* catch clause --- which can be the 'catch' clause
already present in your 'main' function (at least in my 'main' functions).

>>> > Moreover in many interfaces library assumes existence on long
> name,
>>> > short
>>> > name, which may not be the case even with name based parameter
>>> > identification.
>>>
>>> I don't understand what you mean here.
>>
>> > I may not have long name, but only short one, like with old getopt
>> had.
>
>> It's not a problem. You'd still use the long name for identification
>> purposes, but disable long names in command line.
>
> I don't get it. What long name would I use if it only have short name.

Whatever long name you like. You've been talking about maintenance
programmer previously. Now imagine he looks at

   vm["-u"].as<int>()

Fine, what does it mean? Would anyone like to write such criptic code? A
better idea is write

   vm["unified_context_lines"].as<int>()

Now, "unified_context_lines" is the long name, used in program. You can have
only "-u" in command line, no problem.

Note that "-u" probably can be used as key even now. But I think it's very
bad idea.

>> > I may not have short name but only long one, like the style I am
>> > personally prefer.
>
>> What's problem with this case? It's supported out-of-box.
>
> What would you return when user call short name method?

You mean option_description::short_name()? Empty string will be returned.
What's wrong with that?

>>> > 15. External parsers support.
>> > I do not want to store parsed values inside the parser at all. Instead
>> I
>> > want to register for every parameter callback function.
>
>> That's another example I don't see any use for. What will those callback
>> functions do. Can you given some more details why it might be needed?
>
> Let say I have method set_trace_level that manage tracing level for you
> application.
> What I need is in my terms look like this:
> parameter<int>( "trace_level" )
> << default_value( 0 )
> << handler( set_trace_level )
> << description( "specifies the trace level for the application" )
>
> Now when argc/argv parsed argument value is not stored into list of
> parsed argument. Instead
> handler function call and parsed value passed.

The 'notify' function has this functionality. However, it can be called only
*after* parsing. That's an explicit decision -- if you're to support both
string-only interface (syntantic) and typed interface (semantic), you have
to clearly separate the two, and 'notify' belongs to semantic interface.

- Volodya


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk