Program Options Custom Notifier Function Order of Execution

Hi all, Can anyone tell me the precise definition or behaviour of the order of execution of the user supplied functions to handle command line options defined in boost program options library. For example, my option menu was defined as follows boost::program_options::options_description menu("Valid Options"); menu.add_options() ("help,h", "Display this menu.") ("time,t", boost::program_options::value<double>(&time_arg_value) -> notifier(&my_function1) "Description of option") ("memory,m", boost::program_options::value<double>(&memory_arg_value) -> notifier(&my_function2), "Description of option") ("file,f", boost::program_options::value<std::vector<std::string>
(&file_arg_value) -> composing() -> notifier(&file_arg_handler<std::vector<std::string> >), "Something");
boost::program_options::variables_map menu_map; boost::program_options::store(boost::program_options:: parse_command_line(argc, argv, menu), menu_map); boost::program_options::notify(menu_map); Question is: Will the following two calls to the program result in different behaviour?
./Test --time 76 --memory 97 --help ./Test --memory 97 --time 76 --help
I want my two functions for time and memory be independent of each other but I would like the function be called in the same order as the options specified on the command line. Sure I can test but can someone guarantee that what I discovered will remain valid in the future release of the library. Another question: What will happen if this program was called on the command line with the following options.
./Test --file myfile1 --time 87 --file myfile2
Will the file_arg_handler be called first with composed arguments and then time function (my_function1) or will the time function (my_function1) be called first and then the file_arg_handler function. Can I count on it that what happens will always happen in the future? Is there definitions for the order of execution guarantee by the library? Thanks in advance for your help! Best Regards, Tony Han Bao tonybao@mac.com

Hi Tony,
Can anyone tell me the precise definition or behaviour of the order of execution of the user supplied functions to handle command line options defined in boost program options library. ...
For example, my option menu was defined as follows
boost::program_options::options_description menu("Valid Options"); menu.add_options() ("help,h", "Display this menu.") ("time,t", boost::program_options::value<double>(&time_arg_value) -> notifier(&my_function1) "Description of option") ("memory,m", boost::program_options::value<double>(&memory_arg_value) -> notifier(&my_function2), "Description of option") ("file,f", boost::program_options::value<std::vector<std::string>
(&file_arg_value) -> composing() -> notifier(&file_arg_handler<std::vector<std::string> >), "Something");
boost::program_options::variables_map menu_map;
boost::program_options::store(boost::program_options:: parse_command_line(argc, argv, menu), menu_map); boost::program_options::notify(menu_map);
This example misses one important piece -- the call to "nofity" function. As mentioned in http://boost.org/doc/html/program_options/overview.html#id548990 the user-provided notifiers are called by the "program_options::notify" function. The order of invocation is independed of the order on the command line, it's just lexicographical order of the option names.
Question is: Will the following two calls to the program result in different behaviour?
./Test --time 76 --memory 97 --help ./Test --memory 97 --time 76 --help
No.
I want my two functions for time and memory be independent of each other but I would like the function be called in the same order as the options specified on the command line. Sure I can test but can someone guarantee that what I discovered will remain valid in the future release of the library.
Why do you need specific order?
Another question: What will happen if this program was called on the command line with the following options.
./Test --file myfile1 --time 87 --file myfile2
Will the file_arg_handler be called first with composed arguments and then time function (my_function1) or will the time function (my_function1) be called first and then the file_arg_handler function. Can I count on it that what happens will always happen in the future? Is there definitions for the order of execution guarantee by the library?
There's no guarantee at all. The idea is most of the time you don't need specific order. If you describe your problem, I might offer more specific help. - Volodya

On 30 Nov 2004, at 1:33 pm, Vladimir Prus wrote:
Hi Tony,
Hi V, I heard of you before. Thank you for reply.
This example misses one important piece -- the call to "nofity" function. As mentioned in
http://boost.org/doc/html/program_options/overview.html#id548990
the user-provided notifiers are called by the "program_options::notify" function.
I do have a call to notify (See below) in the example but do you mean notify (my_function1) ? boost::program_options::store(boost::program_options:: parse_command_line(argc, argv, menu), menu_map); boost::program_options::notify(menu_map); I don't know if you tried to use this library but it seems the documentation regarding notify is wrong (Or I'm wrong). Try to compile the exact example given by the docs results in an error. replace notify by notifier will cause the function to be called. Maybe I'm missing something here.
The order of invocation is independed of the order on the command line, it's just lexicographical order of the option names.
I don't like this. If what you claim is true then I'm losing control over the program.
Why do you need specific order?
There's no guarantee at all. The idea is most of the time you don't need specific order. If you describe your problem, I might offer more specific help.
What I wanted is to have the user line up their request to the program as options on the command line and each time an option is read, something will happen as the order they were read. I would like to collect some option information as first like files in the example but it's not essential. What you are saying is that these options are treated as arguments to functions but I want them to act more like commands to the program that will cause some action, so any option has a purpose and a place as when and where to be used instead of dumping all to the program as configurations. You seems very certain of what you are saying. Could you send me the link of the documents or notes from the developer of this library that confirm this behaviour?
- Volodya
Thanks again. I hope you don't mind if I put your e-mail address into my address book. I would like to talk again. Regards, Tony Han Bao tonybao@mac.com
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Hi Tony,
the user-provided notifiers are called by the "program_options::notify" function.
I do have a call to notify (See below)
Ok, I just did not see it in your original code snippet.
in the example but do you mean notify (my_function1) ?
No, surely not.
boost::program_options::store(boost::program_options:: parse_command_line(argc, argv, menu), menu_map); boost::program_options::notify(menu_map);
This looks like.
I don't know if you tried to use this library but it seems the documentation regarding notify is wrong (Or I'm wrong). Try to compile the exact example given by the docs results in an error. replace notify by notifier will cause the function to be called. Maybe I'm missing something here.
Can you point me a a specific example which does not compile. While most code in the docs is derived from code in the "example" directory, it's possible that some typo was made.
The order of invocation is independed of the order on the command line, it's just lexicographical order of the option names.
I don't like this. If what you claim is true then I'm losing control over the program.
It depends on your point of view. In my opinion deterministic order of 'notifier' calls is a feature, and each feature must have a real use case to enter a library. Imagine loading options from LDAP server (I hope to implement that one day). Does it make sense to talk about order of the options? Even for config files, the order of options is generally not important.
Why do you need specific order?
There's no guarantee at all. The idea is most of the time you don't need specific order. If you describe your problem, I might offer more specific help.
What I wanted is to have the user line up their request to the program as options on the command line and each time an option is read, something will happen as the order they were read. I would like to collect some option information as first like files in the example but it's not essential.
What you are saying is that these options are treated as arguments to functions but I want them to act more like commands to the program that will cause some action, so any option has a purpose and a place as when and where to be used instead of dumping all to the program as configurations.
This explains something. This also suggests you don't need name->value mapping that's provided by the variables_map class. I would suggest you use the 'parsed_options' class which is returned by the parse_command_line function: typedef basic_parsed_options< char > parsed_options; http://boost.org/doc/html/parse_command_line.html http://boost.org/doc/html/basic_parsed_options.html There are two possibilities: - Each option is a completely independent command. Then you don't need variables_map at all. You just have a map from option name to function that executes the command, and you'll iterate over returned options, calling those functions. - Some options are "commands". Some are ordinary options and affect the execution of commands. Then, code like this would work: parsed_options p = parse_command_line(......); parsed_options p2; p2.description = p.description; for(unsigned i = 0; i < p.options.size(); ++i) { if ( /* p.options[i] is command */ ) { // Store the options found so far to 'vm' variables_map vm; store(p2, vm); notify(vm); // Execute your command, supposedly making use of // options stored in 'vm'. } else { p2.options.push_back(p.options[i]); } } Let me know your opinions on the above approaches. This looks like a candidate for "howto" section of the docs. - Volodya

On 1 Dec 2004, at 11:58 am, Vladimir Prus wrote:
Hi Tony,
Hi Vladimir. Sorry for the late reply.
Can you point me a a specific example which does not compile. While most code in the docs is derived from code in the "example" directory, it's possible that some typo was made.
On page http://www.boost.org/doc/html/program_options/overview.html under semantic information, the following piece of code. options_description desc; desc.add_options() ("compression", "compression level", value<int>()->default(10)); ("email", "email", value< vector<string> >() ->composing()->notify(&your_function); 1) Order of arguments of add_options() are wrong. value<int>()->default(10) is the second argument and "compression level" should be the third argument. And the same order for email option. 2) default(10) should really be default_value(10). 3) There should be no ; at the end of the third line. 4) notify(&your_function) should really be notifier(&your_function) 5) I believe it's a good idea to use full namespace in examples. It helps to know where the functions and classes come from.
The order of invocation is independed of the order on the command line, it's just lexicographical order of the option names.
I don't like this. If what you claim is true then I'm losing control over the program.
It depends on your point of view. In my opinion deterministic order of 'notifier' calls is a feature, and each feature must have a real use case to enter a library. Imagine loading options from LDAP server (I hope to implement that one day). Does it make sense to talk about order of the options? Even for config files, the order of options is generally not important.
Once again, I apologise for the overly strong words used in my first reply (It was a long day). As for the need of such feature: "I am co-developing a Generic SAT library that devotes to General Satisfiability problems in computer science and logic. I would like to provide the user the options to specify their parameters as a sequence of instructions to some application, a SAT solver developed using my library for instance. The instructions could be first generate some random formula with these parameters, try some algorithms on them to solve them for an hour with this amount of memory, stop current job, generate more formula, try different algorithms etc..." And thank you for agreeing with me that this IS a use case.
Why do you need specific order?
There's no guarantee at all. The idea is most of the time you don't need specific order. If you describe your problem, I might offer more specific help.
I must admit that my original e-mail has taken this a little too extreme (all options are commands and none are "options"). Most of the time we don't need specific order which is true for most Unix commands and that's the way people are use to. However, I believe luck favours the prepared. The fundamental principle of writing a library (in my opinion) is to provide easy and friendly functionality that respond to users' need with all (well, most) possibilities.
There are two possibilities:
- Each option is a completely independent command. Then you don't need variables_map at all. You just have a map from option name to function that executes the command, and you'll iterate over returned options, calling those functions.
I admin this is an extreme case. Even with my original design, I would have some real options instead of commands in the mix.
- Some options are "commands". Some are ordinary options and affect the execution of commands.
And this, I believe, is a feature that deserves consideration. The following lines are copied (shortened) from the help menu of utility rar. RAR 3.41 Copyright (c) 1993-2004 Alexander Roshal 2 Nov 2004 Shareware version Type RAR -? for help Usage: rar <command> -<switch 1> -<switch N> <archive> <files...> <@listfiles...> <path_to_extract\> <Commands> a Add files to archive c Add archive comment cf Add files comment cw Write archive comment to file d Delete files from archive e Extract files to current directory f Freshen files in archive i[par]=<str> Find string in archives ... <Switches> - Stop switches scanning ad Append archive name to destination path ag[format] Generate archive name using the current date ap<path> Set path inside archive ... p[password] Set password ... vp Pause before each volume w<path> Assign work directory x<file> Exclude specified file x@ Read file names to exclude from stdin x@<list> Exclude files in specified list file y Assume Yes on all queries z<file> Read archive comment from file Some special syntax are used to separate the commands and the switches (options) which I think is a good idea. Mixing commands and options are not uncommon and the above form of allowing this feature seems a good starting point.
Then, code like this would work:
... your code
Let me know your opinions on the above approaches. This looks like a candidate for "howto" section of the docs.
I had a look and tried it. Thanks. And yes, I hope you add it to the "howto" section. I'm looking forward to hear from you again. Tony
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Tony H. Bao T.H.Bao@Swansea.ac.uk

Hi Tony,
Can you point me a a specific example which does not compile. While most code in the docs is derived from code in the "example" directory, it's possible that some typo was made.
On page
http://www.boost.org/doc/html/program_options/overview.html
under semantic information, the following piece of code.
options_description desc; desc.add_options() ("compression", "compression level", value<int>()->default(10)); ("email", "email", value< vector<string> >() ->composing()->notify(&your_function);
1) Order of arguments of add_options() are wrong. value<int>()->default(10) is the second argument and "compression level" should be the third argument. And the same order for email option. 3) There should be no ; at the end of the third line.
This is already fixed in CVS.
2) default(10) should really be default_value(10). 4) notify(&your_function) should really be notifier(&your_function)
You're right on those points, which are now corrected. Quite a number of typos for a single example ;-)
5) I believe it's a good idea to use full namespace in examples. It helps to know where the functions and classes come from.
Not sure, as everything's from boost::program_options.
It depends on your point of view. In my opinion deterministic order of 'notifier' calls is a feature, and each feature must have a real use case to enter a library. Imagine loading options from LDAP server (I hope to implement that one day). Does it make sense to talk about order of the options? Even for config files, the order of options is generally not important.
Once again, I apologise for the overly strong words used in my first reply (It was a long day).
No problem.
As for the need of such feature:
"I am co-developing a Generic SAT library that devotes to General Satisfiability problems in computer science and logic. I would like to provide the user the options to specify their parameters as a sequence of instructions to some application, a SAT solver developed using my library for instance. The instructions could be first generate some random formula with these parameters, try some algorithms on them to solve them for an hour with this amount of memory, stop current job, generate more formula, try different algorithms etc..."
And thank you for agreeing with me that this IS a use case.
For the list readers: the above is quotation from email that Tony sent me offlist. I agree this is a valid use case.
- Some options are "commands". Some are ordinary options and affect the execution of commands.
And this, I believe, is a feature that deserves consideration. The following lines are copied (shortened) from the help menu of utility rar.
RAR 3.41 Copyright (c) 1993-2004 Alexander Roshal 2 Nov 2004 Shareware version Type RAR -? for help
Usage: rar <command> -<switch 1> -<switch N> <archive> <files...> <@listfiles...> <path_to_extract\>
...
Some special syntax are used to separate the commands and the switches (options) which I think is a good idea.
boost::program_options uses "--" for that purpose.
Then, code like this would work:
... your code
Let me know your opinions on the above approaches. This looks like a candidate for "howto" section of the docs.
I had a look and tried it. Thanks. And yes, I hope you add it to the "howto" section.
Great. I'll add it soon. BTW, I have another idea. If you have "options" and "command" and the order of "options" is not important, then you can make command into positional options, something like: prog --mmx do_this do_that When parsing 'do_this' and 'do_that' like positional options, they will be stored in the same order they were specified. Of course, if you need to interleave options and commands and command should be influenced only by preceeding options, the code that I've given is the only way. I'll document this and think if some simplification is possible. - Volodya

On Sun, 5 Dec 2004 22:42:52 +0000, Tony Han Bao <tonybao@mac.com> wrote:
RAR 3.41 Copyright (c) 1993-2004 Alexander Roshal 2 Nov 2004
Please do not hold up RAR as a shining example of how command line options should be specified or parsed. It is right up there with "tar" and "dd" in terms of its cryptic and unconventional command line format. Unlike those venerable utilities, however, it was not written before these conventions became common, so it has no excuse for this behavior. -- Caleb Epstein caleb dot epstein at gmail dot com

Hi Caleb, On 6 Dec 2004, at 13:12, Caleb Epstein wrote:
RAR 3.41 Copyright (c) 1993-2004 Alexander Roshal 2 Nov 2004
Please do not hold up RAR as a shining example of how command line options should be specified or parsed. It is right up there with "tar" and "dd" in terms of its cryptic and unconventional command line format.
My idea was that a program could take both commands and options on the command line. Commands cause the program to "react" immediately as they were read in the order that they were specified whereas options set the environment for the reaction and govern it. For demonstration purpose, I simply used RAR as an example which clearly mixes commands and options for one program. This interpretation may not be so common but I do believe it's worthy of further discussion. While we are on the topic, I'm curious, which utility should be hold up as a shining example? Does one that satisfies all even exist?
Unlike those venerable utilities, however, it was not written before these conventions became common,
This may be true...
so it has no excuse for this behavior.
But since when does providing alternative needs an excuse. Criticism on its own resolves nothing. They should be accompanied with suggestions which eventually lead to improvements. After all, we are all here for one reason: help perfect boost and in turn perfect ourselves. Sincerely, Tony Han Bao tonybao@mac.com

Tony Han Bao wrote:
While we are on the topic, I'm curious, which utility should be hold up as a shining example?
Yes, IMO subversion command line client is a nice example. - Volodya
participants (3)
-
Caleb Epstein
-
Tony Han Bao
-
Vladimir Prus