関数の引数について

function toaru_kagakuno_function($method, $url, $hoge, $fuga, $piyo, ...){
    何かしらの処理
}

toaru_kagakuno_function('GET', $url, $hoge, $fuga, $piyo, ...);

PHPでとあるメソッドを実装しようとして、引数が多くなってしまった。あんまり多いと引数の順序なんか覚えられないし、どれをどの順で渡すようにしようかとか考えると悩んでるだけで1時間が過ぎてしまう。そこで、引数を連想配列に入れて渡すことにした。

function toaru_kagakuno_function($args){
    ...
    $url_elements = parse_url($args['url']);
    ...
    何かしらの処理
    ...
    $request = $args['method'].' '.$url_elements['path'].'?'.$url_elements['query'].' HTTP/1.0\r\n';
    ...
}
$args = array(
     'method' => 'GET'
    ,'url' => $url
    ,'hoge' => $hoge
    ,'fuga' => $fuga
    ,'piyo' => $piyo
    ...
);
toaru_kagakuno_function($args);

しかし、$args['method']や$args['url']は毎回必ず指定する必要があるので、助長だなと思い次のように書きなおした。

function toaru_kagakuno_function($method, $url, $args){
    ...
    $url_elements = parse_url($url);
    ...
    何かしらの処理
    ...
    $request = $method.' '.$url_elements['path'].'?'.$url_elements['query'].' HTTP/1.0\r\n';
    ...
}
$options = array(
     'hoge' => $hoge
    ,'fuga' => $fuga
    ,'piyo' => $piyo
    ...
);
toaru_kagakuno_function($method, $url, $options);

CやJavaなど、(少なくとも自分の知る範囲では)多くの言語では引数が配列のようになっている。すなわち、順序を持ったデータ列である。しかし、場合によっては順序が不要などころか煩わしい場合もある。そういうときは、もし言語に連想配列(Rubyなどではハッシュと呼ばれる)を利用したら良いかもしれない。連想配列を用いることで、引数の順序を無くすことができる。この発想はJavaScriptのライブラリであるjQueryajaxメソッドから得た。もしC言語を使っているのであれば、引数をまとめた構造体を定義するといいかもしれない。WinAPIの多くの関数は引数に構造体のポインタを渡すようになっている。
ただ、全ての引数を連想配列にまとめることはない。”必ず”指定する必要があり、かつその数が少ないのであれば、上記のように順序付き引数と連想配列を混ぜるといいと思う。”options”が意味するように、連想配列にはオプションで指定してもしなくてもいいものを束ねる。これで、順序付きの引数では実現できなかった、”いくつかの引数のうちどれかを省略する”ということができる。

function toaru_majutsuno_function($hoge = 'HOGE', $fuga = 'FUGA'){
    何かしらの処理
}

// こうは書けても
toaru_majutsuno_function('hoge');
// こう書くことはできない!
//toaru_majutsuno_function(, 'fuga');
// この場合はこう書かないといけない
toaru_majutsuno_function('HOGE', 'fuga');

C++PHPのような言語のデフォルト引数の機能では、必ず後ろから省略しないといけないので、連想配列にすることはそういう点でも意味がある。(どの言語でもデフォルト引数の省略は後ろからかと思ったけど、自分が最初に知ったHSPという言語は任意の引数を省略して書くことができた。)

以上のことを纏めると、引数に連想配列を使う利点は次のような場合にある。

  • 引数が多くて覚えきれない
  • 省略可能な引数が2つ以上あって、それらが順番に依らない。