###
2 新しいアクションの追加

新しいアクションの追加はもう少しトリッキーです。というのも `optparse` が使っている二つのアクションの分類を理解する必要があるからです。

``store'' アクション
  `optparse` が値を現在の OptionValues の属性に格納することになるアクションです。 この種類のオプションは Option のコンストラクタに `dest` 属性を与えることが 要求されます。
``typed'' アクション
  コマンドラインから引数を受け取り、それがある型であることが期待されているアクションです。 もう少しはっきり言えば、その型に変換される文字列を受け取るものです。 この種類のオプションは Option のコンストラクタに `type` 属性を与えることが 要求されます。

この分類には重複する部分があります。デフォルトの ``store'' アクションには `store`、`store_const`、`append`、`count` などがありますが、 デフォルトの ``typed'' オプションは `store`、`append`、`callback` の三つです。

アクションを追加する際に、以下の Option のクラス属性(全て文字列のリストです) の中の少なくとも一つに付け加えることでそのアクションを分類する必要があります。

`ACTIONS`
  全てのアクションは ACTIONS にリストされていなければなりません
`STORE_ACTIONS`
  ``store'' アクションはここにもリストされます
`TYPED_ACTIONS`
  ``typed'' アクションはここにもリストされます
`ALWAYS_TYPED_ACTIONS`
  型を取るアクション (つまりそのオプションが値を取る) はここにもリストされます。 このことの唯一の効果は `optparse` が、型の指定が無くアクション が `ALWAYS_TYPED_ACTIONS` のリストにあるオプションに、 デフォルト型 `string` を割り当てるということだけです。

実際に新しいアクションを実装するには、Option の `take_action()` メソッドをオーバライドしてそのアクションを認識する場合分けを追加しなければなりません。

例えば、`extend` アクションというのを追加してみましょう。このアクションは 標準的な `append` アクションと似ていますが、コマンドラインから一つだけ値を 読み取って既存のリストに追加するのではなく、複数の値をコンマ区切りの文字列として 読み取ってそれらで既存のリストを拡張します。すなわち、もし `"-names"` が `string` 型の `extend` オプションだとすると、次のコマンドライン

    --names=foo,bar --names blah --names ding,dong

の結果は次のリストになります。

    ["foo", "bar", "blah", "ding", "dong"]

再び Option のサブクラスを定義します。

    class MyOption (Option):

        ACTIONS = Option.ACTIONS + ("extend",)
        STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
        TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
        ALWAYS_TYPED_ACTIONS = Option.ALWAYS_TYPED_ACTIONS + ("extend",)

        def take_action(self, action, dest, opt, value, values, parser):
            if action == "extend":
                lvalue = value.split(",")
                values.ensure_value(dest, []).extend(lvalue)
            else:
                Option.take_action(
                    self, action, dest, opt, value, values, parser)

注意すべきは次のようなところです。

- `extend` はコマンドラインの値を予期していると同時にその値をどこかに格納します ので、`STORE_ACTIONS` と `TYPED_ACTIONS` の両方に入ります。

- `optparse` が `extend` アクションに `string` 型を割り当てるように `extend` アクションは `ALWAYS_TYPED_ACTIONS` にも入れてあります。

- `MyOption.take_action()` にはこの新しいアクション一つの扱いだけを 実装してあり、他の標準的な `optparse` のアクションについては `Option.take_action()` に制御を戻すようにしてあります。

- `values` は optparse_parser.Values クラスのインスタンスであり、 非常に有用な `ensure_value()` メソッドを提供しています。 `ensure_value()` は本質的に安全弁付きの `getattr()` です。 次のように呼び出します。

      values.ensure_value(attr, value)

  `values` に `attr` 属性が無いか None だった場合に、 `ensure_value()` は最初に `value` をセットし、 それから `value` を返します。 この振る舞いは `extend`、`append`、`count` のように、データを変数に 集積し、またその変数がある型 (最初の二つはリスト、最後のは整数) であると期待されるアクション を作るのにとても使い易いものです。`ensure_value()` を使えば、 作ったアクションを使うスクリプトはオプションに保存先にデフォルト値をセットすることに 煩わされずに済みます。デフォルトを None にしておけば `ensure_value()` が それが必要になったときに適当な値を返してくれます。