可変長引数が抱える心の闇
PHP、JavaScriptそれぞれの可変長引数サポートという記事で扱ったテクニック、可変長引数。関数定義でarg1,arg2,arg3…と続ける事無く、スマートに引数を取り出す事が出来ます。
しかしながら、引数にローカル変数を充てないという事は、関数内での引数の引き渡しで困難に出会います。
//PHP function dullfunction(){ $args = func_get_args(); otherfunction($args); } //想定した動作をしてくれません。 |
動作が想定通りいかないのは、当たり前の事です。この書き方ですと、関数otherfunction()に配列$argsへの参照が与えられるだけで、したがってotherfunctionの中では$argsを参照した1つの引数が与えられたものと見なされてしまいます。
それならば、引数の一つ一つを$args[0],$args[1]…のように分けて渡せば良い!と思われるかもしれませんが、それは可変長引数という前提に忠実ではありません。
そこで、そもそも関数に引数として配列を渡せないのはおかしいと上司に叛旗を翻してみて下さい。数十社クビになった後、親切な上司が(もしいればですが)教えてくれます。
PHP、JavaScriptで配列を関数の引数として与える方法
PHP、JavaScriptともに、配列を要素分だけ引数として与える方法があります。
//PHP function dullfunction(){ $args = func_get_args(); call_user_func_array("otherfunction", $args); } |
PHPでは、call_user_func_array()という関数を用います。第一引数には、関数の名前を指定します。このとき()はつけません。また、以下のように第一引数に無名関数をとる事も出来ます。
//PHP function dullfunction(){ $args = func_get_args(); call_user_func_array(function(){$args2 = func_get_args(); print_r($args2);}, $args); } //無名関数の中でcall_user_func_array("dullfunction",$args2);とかやってはいけない |
ところで、このcall_user_func_array()について、あちこちの説明でまるでユーザが定義した関数でないと動かないかのような誤解を与える表現をしていますが、別に普通の関数(var_dumpとか…)を与えても動いてくれます。便利ですよ。
お次はJavaScriptの場合です。
//JavaScript function dullfunction(){ otherfunction.apply(this,arguments); } |
可変長だろうがそうでなかろうが、JavaScriptの引数がargumentsで取れるという事は既に説明しました。今回新しく登場したapplyというfunctionオブジェクトのメソッドは、メソッドを呼び出した関数の中の”this”キーワードに別の値を代入するという、火星人が作ったようなよくわからない働きをするメソッドですが、第二引数には配列またはオブジェクトで呼び出し元関数への引数を与える事が出来るようになっています。
//JavaScript function.apply(引数1,引数2); //引数1:関数内の"this"に充てるもの。ただ可変長引数を与えたいだけならthisを指定し //この部分の働きを殺す。 //引数2:関数に与える引数 |
きっと親切に教えてくれる上司は火星人です。即刻辞表を突き付けましょう。
ピンバック: PHP、JavaScriptそれぞれにおける無名関数 | AkisiのWEB制作日記