The next protocol we need to implement is the so-called argument
conversion protocol. This protocol is used to convert option arguments
(that is, strings) to an actual value of the proper type. Arguments
going through this protocol come from the command-line, the value of an
environment variable or a debugger restart (see Error
Management in The Clon End-User Manual). Also, note that Clon
assumes that you implement this
protocol correctly, so no value check is performed on values coming from
the conversion of an argument.
The conversion protocol is implemented through a convert
generic
function for which you must provide a method.
Convert ARGUMENT to OPTION’s value. If ARGUMENT is
invalid, raise an invalid-argument
error.
As you can see, you need to provide a method with the first argument
specialized to your new option type. This method must return the
conversion of ARGUMENT to the appropriate type if it is valid, and
raise an invalid-argument
error otherwise.
The invalid-argument
error condition is defined like this:
(define-condition invalid-argument (option-error) ((argument :documentation "The invalid argument." :type string :initarg :argument :reader argument) (comment :documentation "An additional comment about the error." :type string :initarg :comment :reader comment)) (:report (lambda (error stream) (format stream "Option ~A: invalid argument ~S.~@[~%~A~]" (option error) (argument error) (comment error)))) (:documentation "An invalid argument error.")) |
When the error is raised, you must fill in the argument
and
comment
slots appropriately.
As before, the super-condition option-error
provides an
additional option
slot that you must also fill in when the error
is raised.
Let’s look at the enumeration example now.
(defmethod convert ((enum enum) argument) "Convert ARGUMENT to an ENUM value." (or (closest-match argument (enum enum) :ignore-case t :key #'symbol-name) (error 'invalid-argument :option enum :argument argument :comment (format nil "Valid arguments are: ~A." (list-to-string (enum enum) :key (lambda (value) (stringify enum value))))))) |
Since enumerations allow their arguments to be abbreviated, a utility
function named closest-match
is used to find the closest match
between an argument and the possible values. Otherwise, an
invalid-argument
error is raised. For an explanation of
stringify
, See Value Stringification Protocol.