5.1.6 Constructor Functions

The last required step to complete our new option type extension is to provide a constructor function that wraps around make-instance on the corresponding option class. I won’t insult you by explaining how to write a constructor. Let me just give four good reasons why providing constructors is important.

Providing a constructor for every new option type is important because:

  1. it is important,
  2. it is a good software engineering practice,
  3. it is important,
  4. and above all, it makes your new option type automatically available in calls to defsynopsis and defgroup (see Synopsis Items and Group Definition).

Let’s look at the enumeration example now.

(defun make-enum (&rest keys
                  &key short-name long-name description
                       argument-name argument-type
                       enum env-var fallback-value default-value
                       hidden)
  "Make a new enum option.
- SHORT-NAME is the option's short name (without the dash).
  It defaults to nil.
- LONG-NAME is the option's long name (without the double-dash).
  It defaults to nil.
- DESCRIPTION is the option's description appearing in help strings.
  It defaults to nil.
- ARGUMENT-NAME is the option's argument name appearing in help strings.
- ARGUMENT-TYPE is one of :required, :mandatory or :optional (:required and
  :mandatory are synonyms).
  It defaults to :optional.
- ENUM is the set of possible values.
- ENV-VAR is the option's associated environment variable.
  It defaults to nil.
- FALLBACK-VALUE is the option's fallback value (for missing optional
  arguments), if any.
- DEFAULT-VALUE is the option's default value, if any.
- When HIDDEN, the option doesn't appear in help strings."
  (declare (ignore short-name long-name description
                  argument-name argument-type
                  enum env-var fallback-value default-value
                  hidden))
  (apply #'make-instance 'enum keys))

Woah, what a mouthful for a single line of code… Yeah, I’m a maniac and I like redundancy. I always restate all the available keys explicitely, and everything again in the docstring so that all the interesting information is directly available (I might change my mind as I grow older though).