If you are just interested on getting an idea of what OptiFlag does click on home to gently walk through a command-line scenario. This page is a quick reference for those using OptiFlag. After the terminology section is a list of the flag-set declarations, clause-level modifiers and special-directives that make OptiFlag what it is: a DSL for command-line parsing.
Terminology
The below example introduces two terminology items that are the purpose of this quick reference page: flag declarations and clause-level modifiers. After this example we list and describe the members of each category. To see these at work, check out the examples.
|
Example explanationThe image to the left shows a typical OptiFlag scenario. You will note that there is a natural indentation. First off, everything between the module start and end is considered to be in the OptiFlag DSL zone.module Example extend OptiFlagSet # all code here is in # the OptiFlag DSL zone end Next, our indentation shows what are called flag declarations. Flag declarations create a flag, switch, argument or keyword for the command line. Our example and key shows four flag declarations (two "flag" declarations and two "optional_flag" declarations). Next, are what we call clause-level modifiers. These modify the actual flag to change its attributes. Often times the flag declarations are merely short-hand notation for the standard "flag" declaration. For instance. optional_flag "verbose" flag "verbose" do optional end In this example, there are three clause-level modifiers: two value_matches and one value_in_set. |
Flag declarations
(as is good practice, the RDoc for OptiFlag::Flagset always has the complete details)flag | optional_flag | optional_switch_flag | character_flag | usage_flag | keyword | flag_properties |
| flag |
Example Declaration:
flag "username"
All other flags ultimately use this code as a default and then use clause-level modifiers appropriately. | |||
| optional_flag |
Just like a regular flag, but required is set to false
Declaration: optional_flag "message"
The key to using an optional flag (after the above declaration) is to call the question-mark method of the 'flags' attribute. The entire code would look something like: module MyVersionController extend OptiFlagSet optional_flag "message" and_process! end if ARGV.flags.message? record_message(ARGV.flags.message) end As you can see above, every optional flag (switch or not) has a parallel set of question-mark attributes (as you all know, attributes are merely methods) which return true or false depending upon whether the user has set the option on the command-line. >
ruby fooBar.rb -message "This is a message I am passing to the program."
You can also see how the question mark attribute (ARGV.flags.message?) is used to query whether the user set the flag, and the non-question-mark (ARGV.flags.message) has the actual value. | |||
| optional_switch_flag |
An optional_switch_flag is a flag declaration that creates an optional flag with zero arity -- that is a dash-argument which should either be present or not. optional_switch_flag "deleteDB" >
-deleteDB
The key to using a switch flag (after the above declaration) is to call the question-mark method of the 'flags' attribute. The entire code would look something like: module OptionalArgs extend OptiFlagSet optional_switch_flag "deleteDB" and_process! end run_delete() if ARGV.flags.deleteDB? # remember you can also use the following: # run_delete() if OptionalArgs.flags.deleteDB? # because OptiFlag augments the module # as well as ARGV. It's your personal choice As you can see above, every flag (switch or not) has a parallel set of question-mark attributes (as you all know, attributes are merely methods) which return true or false depending upon whether the user has set the option on the command-line. | |||
| character_flag |
Example Declaration:character_flag :f A 'character_flag' is just like an optional_switch_flag in that it is optional and has zero arity. It is distinguished by the fact that it can only be one character long and (much more importantly) that it takes a second optional argument (VERY IMPORTANT TO NOTE THAT THIS IS PART OF THE DECLARATION TIME) that indicates to what group it can cluster with. Imagine the following example code: module TestArgs extend OptiFlagSet character_flag :l, :list_group character_flag :s, :list_group character_flag :a, :list_group and_process! end This second optional argument (the cluster group) :list_group allows OptiFlag to understand that these characters may be clustered together on the command line and re-arranged in any order. For instance, the following (incomplete) samples will all parse the same: >ruby helloWorld.rb -lsa
>ruby helloWorld.rb -l -s -a
>ruby helloWorld.rb -l -as
>ruby helloWorld.rb -al -s
See this example. This current implementation of clustering where character flags who wish to declare themselves part of a cluster must declare the same symbol as their second argument might be replaced by something more elegant in the future. See this discussion for a possible new way to declare the existence of clusters (not part of the current functionality). | |||
| usage_flag |
A special flag that creates a flag that is used by the OptiFlag system to activate the help system. If you use the and_process! special-directive at the bottom of the module declaration, then you will automatically be given '-h' and '-?' as help flags. You may choose to add to these by using the declaration as such: usage_flag "help", "ayudame" where the 'usage_flag' directive is followed by a list of other flags that will be used as help flags. The help flag has two special properties:
Another point of interest is that 'usage_flag' does not have a block following it. This means that if you want to add clause-level modifiers to it, you will need to use flag_properties on :h to re-open the flag. | |||
| keyword |
A keyword is an optional flag with zero arity and with no dash symbol
(either short or long form). The idea of this flag declaration
was (possibly) to support the command system of such programs like
CVS (or SVN) in which the first argument (not flag) was the main command.
>CVS checkout * -v -log c:/tmp
>CVS tag -message "Release 0.6.5" -log c:/tmp
As it stands right now, 'keyword' may be used for this purpose (it's up to
you) but the author reserves the right to come up with a better solution
in the future.
| |||
| flag_properties |
Re-open the flag declaration for additional clause-level
modifications. I got the idea for this from Rake. In Rake, a task
is never closed. And likewise, Rake got this idea from Ruby itself as
a class and/or module is never closed and a developer may add, change,
or subtract from the existing code base.
The following two are equivalent: module Example extend OptiFlagSet optional_flag "mode" do # this is our second new clause-level modifier value_in_set ["read","write","execute"] description "The permission mask the program shall apply to the doohickey" end and_process! end module Example extend OptiFlagSet optional_flag "mode" flag_properties :mode do value_in_set ["read","write","execute"] description "The permission mask the program shall apply to the doohickey" end and_process! end |
Clause-level modifiers
description | arity | required | optional | values_in_set | dash_symbol | alternate_forms | long_form | no_args | one_arg | default | long_dash_symbol | alternate_forms |
| description |
Declaration:
flag "username" do description "Your AFS username" end |
| arity |
Tells OptiFlag how many parameters must follow the flag. For instance, suppose you wanted to d
>ruby myProgram.rb -credentials daniel ch3ckm8
flag "credentials" do arity 2 end |
| required | |
| optional | |
| values_in_set | |
| dash_symbol | |
| alternate_forms | |
| long_form with_long_form | |
| no_args | |
| one_arg | |
| default | |
| long_dash_symbol | |
| alternate_forms |
Special directives
and_process! |
| and_process! |

