Array#extract_options! で Rails API のように柔軟な引数を取るメソッドを定義する

こんにちは、鈴木です。

Rails が提供する API の特徴として、引数の指定が柔軟である点が挙げられると思います。

 

柔軟な引数の指定

例えば、一括代入を許可する属性を指定する attr_accessible メソッドは、以下のように色々な呼び出し方をすることができます。

引数は一つ指定しても複数指定しても良く、:as => :admin のようにオプションを指定することもできます。

attr_accessible 以外にもルーティング定義で使用する resources や、エラーハンドリングを行なう rescue_from など、多くのメソッドが引数を柔軟に指定することができます。

引数を柔軟に指定することができるメソッドの定義を確認すると、以下のように可変長引数を取るようになっています。

使う側からすると引数指定が柔軟であると便利ですが、そのようなメソッドを書いた人は可変長引数を適切に処理するコードをメソッドの先頭で一生懸命書いているのでしょうか。

 

Array#extract_options!

Array#extract_options! を使用すると attr_accessible などのように柔軟な引数指定ができるメソッドを簡単に書くことができます。

Array#extract_options! は ActiveSupport で以下のように定義されています(activesupport-3.2.9 で確認)。

中身は単純で、配列の最後の要素が Hash かつ extractable_options? が true なら、配列の最後の要素(Hash)を取り出す、そうでなければ空の Hash を返します。

つまり、Array#extract_options! は可変長引数からハッシュで指定されたオプションを取り出すためのメソッドです。

動作を確認するために、以下のメソッドを定義し、色々なパターンで引数を渡してみます。

まずは引数を指定しない場合です。

引数を一つだけ指定します。

引数を複数指定すると、以下のようになります。

今度はハッシュでオプションも指定してみます。

ハッシュのオプションだけ指定すると次のようになります。

Array#extract_options! を使用すると、「引数はいくつでも指定可能(可変長)、オプションがある時はハッシュで指定する」というパターンのメソッドを簡単に書くことができます。

 

Array#extract_options! の使用例

具体的な使用例ということで、URL パラメータの一部を遷移先に引き継ぐでご紹介した、take_params を再掲します。

 

まとめ

Array#extract_options! を使用すると柔軟な引数指定が可能なメソッドを簡単に定義できます。

ただし、柔軟な引数指定ができることと引き替えに、メソッドが可変長引数を取るようになっている点は要注意です。

「def func(*args)」というコードから読み取れることは、あまり多くありません。

メソッドを使う人が困らないように、

  • ドキュメンテーションコメントをしっかり記述する。
  • 「def func(values, options={})」 で十分な場合に、わざわざ可変長引数にしない。

といったところがポイントだと思います。

 

Comments are closed, but you can leave a trackback: Trackback URL.