Module OptiFlag
In: ../src/optiflag-help.rb
../src/optiflag-parse.rb
../src/optiflag.rb

OptiFlag is the module that provides namespacing for the entire optiflag functionality. For usage and examples, see optiflag.rubyforge.org

Terminology

Please treat the following terminology as specific only to the OptiFlag code suite. In the remaining RDoc, we shall try to emphasize this consistent terminology with italics. If you see an italicized phrase, chances are that it is defined here.

Flag Set Declaration

A flag set declaration is a set of flag declarations created by the user of the OptiFlag suite and corresponds to the following code snippet:

  module AppArgs extend OptiFlagSet
     # individual flag declaration goes here ...
     # ... and here
  end

In this case, the module AppArgs is a flag set declaration, and all code within the module definition (i.e. up to the end of end of the module) is either a flag declaration or a special command.

Another way to treat this declaration is as a demarcation between the normal Ruby world and the mini-DSL (Domain Specific Language) that OptiFlag offers. In this view, the declaration provides a DSL-zone in which the DSL is allowed.

  module AppArgs extend OptiFlagSet
     # DSL-zone
     # DSL-zone  (for declaring and modifying flags)
     # DSL-zone
  end

the first line

  module AppArgs extend OptiFlagSet

is really just rote.

Supply your own module argument name and make sure it extends this OptiFlag::Flagset as is written. You will then have a scoped space to write in a command line DSL.

Flag Declaration

A flag declaration is placed within a flag set declaration to indicate that one input parameter per declaration is requested from the command line. A flag declaration is the mini-DSL‘s main programming construct. In the following code, four flag declarations are placed within the overall flag set declaration named AppArgs:

    module AppArgs extend OptiFlagSet
      flag "dir"
      flag "log"
      flag "username"
      flag "password"
    end

Please note that there are other flag set declaration nouns other than flag. For instance in the following snippet:

    module Example extend OptiFlagSet
      flag "dir" do
        alternate_forms "directory","D","d"
        description "The Appliction Directory"
      end
      optional_flag "log" do
        description "The directory in which to find the log files"
        long_form "logging-directory" # long form is keyed after the '--' symbol
      end
      flag "username", :description => "Database username."  # alternate form
      flag "password" do
        description "Database password."
      end
      usage_flag "h","help","?"
      extended_help_flag "superhelp"

      and_process!
    end

there are six flag declarations in total:

  • a flag named "dir"
  • an optional flag named "log"
  • a flag named "username"
  • a flag named "password"
  • a usage flag for summoning help on how to use the flags
  • an extended help flag for summoning detailed usage for the flags

Everything else is either a clause level modifier (e.g. alternate_forms, description, etc.) or a special command.

For a list of all flag set declarations and how to use them, see the RDoc for the OptiFlag::Flagset module.

Clause Level Modifier

As seen above, a clause level modifier is a word used to modify the basic flag, usually within a nested do block. It it this nesting which has inspired the use of the word clause. For instance:

    module Example extend OptiFlagSet
      flag "dir" do
        alternate_forms "directory","D","d"
        description "The Appliction Directory"
      end
    end

We could read this as a sentence: ‘Create a flag "dir" which has three alternate forms "directory", "D", and "d" and which has a description that reads "The Application Directory’.

For the most part, these clause level modifiers are nested within a do-block, though OptiFlag allows us to conserve vertical space by using symbol hashes. (It is recommended that one only uses these in simple cases). For instance, the following two flag set declarations are equivalent:

    module Example extend OptiFlagSet
      flag "username", :description => "Database username."  # alternate form

      and_process!
    end

and

    module Example extend OptiFlagSet
      flag "username" do
         description "Database username."
      end

      and_process!
    end

with the first being a syntactically friendly hash of the clause level modifier as a symbol pointing to the value of the modification.

For a complete list of clause level modifiers see the RDoc for OptiFlag::Flagset::EachFlag

Methods

Classes and Modules

Module OptiFlag::Flagset

Constants

VERSION = "0.7"

Public Class methods

This is a method that looks like a module. It is an excellent example of the syntactic tricks that ruby permits us. This method allows us to provide code like the following:

   module Example extend OptiFlagSet(:flag_symbol => "/")
     flag "dir"
     flag "log"
     flag "username"
     flag "password"

     and_process!
   end

You will note that the top line looks a lot like the standard top line

   # our top line
   module Example extend OptiFlagSet(:flag_symbol => "/")

versus

   # standard top line
   module Example extend OptiFlagSet

The difference is that while the latter (a standard top line) is a reference to a module, the former is a call to this method, that returns the OptiFlag::Flagset module with some defaults changed.

As of now the only symbol/method supported by this method that looks like a module, is the ‘OptiFlag::Flagset.flag_symbol’ class method.

For those still not understanding the syntactic trick, or who find it odd, consider that something similar to this is done in the ruby core language using the proxy/delegate pattern. (See delegate.rb in the Ruby core library)

  class Tempfile < DelegateClass(File)
    # ...
    # ...
  end

You will note that the DelegateClass() is also a method that superficially resembles a class that parameterizes itself. This can be done because Ruby expects:

   class <identifier>  <  <expression>

and not

   class <identifier>  <  <identifier>

like some other languages. And likewise

   module <identifier> extend  <expression>

which allows us to create this method which has the exact same name as the module. Clever ruby.

Special command (at the same level as a flag declaration)

[Validate]