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 explanation

The 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"
is short for
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"
This is the default declaration. Will create a flag with the following qualities (these are the default clause-level modifiers):
  • one argument
  • required
  • uses the default flag symbol (usually, just a dash '-')
  • makes the long-form the exact same as the short form (and preceeded by, usually, a double-dash '--')
  • Accessible via an attribute with the same name as the flag as it was declared, such that ARGV.flags.username will contain the value.
  • Accessible (also) via a hash-lookup on the 'flags' attribute of the module name OR ARGV, such that ARGV.flags["username"] will contain the value.

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"
This is just the same as if you were to use a regular 'flag' declaration with an 'optional' clause-level modifier.
optional_flag "message"
flag "message" do
   optional
end

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:

  1. It automatically stops command line processing when a help flag is detected.
  2. It is both a zero and a one arity method. This allows us to use help to target a specific flag for help and as a general trigger of all the help flags.

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!