関数パラメータ
関数パラメータ というのはヘルプのタイトルで
業界の方々はこういう言葉を常用しているのかもしれないが
私なんかに分かりやすく言うと 関数の引数 の話。
(まぁ 同じか・・・)
本来 AS3 の話で FB4 とは直接は関係ないのだが
Flash Builder 4 -> library -> Debug
でDLしてきたコードを見て発見し、調べていっぱいビックリしたのと
FB4 でも便利に使えそうなので(実際に使われてるし)、FB4 カテゴリにも登録。
何にビックリしたか、というお話。
前述の Debug という外部クラスの関数宣言が
[as3]public static function dump(o:Object,…rest):String[/as3]
となっていた。
先ずここでビックリ! …rest ???!
VB を触っていた頃に ByVal, ByRef なんていう感じで意識していたが
最近はすっかり忘れていた。
PHP では、参照渡しを使わずにコーディングしてたんだなぁ。。。
引数をコピーする。
関数内で代入された値は関数内でのみ有効で、関数外には影響がない。
よって、関数外でも新しい値を用いたいなら return で値を戻してやる必要がある。
引数の参照を渡す。
つまり、関数内でその引数(変数)を操作すると、それが全体に反映される。
という風に
ActionScript 言語とシンタックス / 関数:関数パラメータ
を読んでいて「値渡し」と「参照渡し」について再認識した。
AS3 では
- プリミティブ型は「「値渡し」
- オブジェクト型は「参照渡し」
なのだそうだ。
引数は受け取る側でデフォルト値を設定できる。
これによって、呼び出し時に引数を省略した場合は、デフォルト値が用いられる。
[as3]function defaultValues(x:int, y:int = 3, z:int = 5):void
{
trace(x, y, z);
}
defaultValues(1); // 1 3 5[/as3]
今まで PHP からの流れで何気なく使ってきたが
このは AS3 の新機能なんだそうで、これまたビックリ。
私は「オブジェクト」という言葉にどうも慣れなくて、ついつい「配列」をイメージしてしまう。
これは早く直さないとなぁ。
さて、脱線してしまったが、本題はここから。
AS3 では、受け取り引数をオブジェクト化できる(してある)。
具体的には、以下のように書くことができる。
[as3]function (x:int, y:String, z:Number)
↓
function (… args)[/as3]
これはすごいいいいいいいい!
[as3]function example(… args):void {
myTextArea.text = Debug.dump(args); // 前述の Debug クラスを利用
}
example(2, “hoge”, 5.5);
// Array (3) {
// [0] =>
// int(2)
// [1] =>
// String (4) = “hoge”
// [2] =>
// Number(5.5)
// }[/as3]
この便利な機能には
- arguments オブジェクト
- …(rest) パラメータ
の2種類の用法があるが、同時に用いることはできない。
関数に引数を送った時点で、自動的に生成されている arguments オブジェクト。
- arguments オブジェクトは、関数に渡されるすべてのパラメータを含む配列です。
- arguments.length プロパティは、関数に渡されるパラメータの数を報告します。
- arguments.callee プロパティを使用すると、関数自体を参照することができます。これは関数式の再帰呼び出しに便利です。
以下のように宣言なしでいきなり利用可能。
[as3]function example(x:int, y:String, z:Number):void {
for (var i:int = 0; i < arguments.length; i++) {
trace(arguments[i]);
}
}
example(2, "hoge", 5.5);
// output:
// 2
// hoge
// 5.5[/as3]
これならば、引数の一括処理が可能。
ヘルプにある
[as3]function traceArgArray(x:int):void
{
for (var i:uint = 0; i < arguments.length; i++)
{
trace(arguments[i]);
}
}
traceArgArray(1, 2, 3);
// output:
// 1
// 2
// 3[/as3]
このコードを試してみたけど「引数の数が合わない」と怒られた。
Flex だから?
arguments.callee 利用例
[as3]var factorial:Function = function (x:uint)
{
if(x == 0)
{
return 1;
}
else
{
return (x * arguments.callee(x - 1));
}
}
trace(factorial(5)); // 120[/as3]
以上のような素敵な機能があるので、arguments という名称の変数は使わないようにする。
ActionScript 3.0 は、…(rest) パラメータと呼ばれる新しいパラメータ宣言を導入しています。
このパラメータを使用すると、任意の数のカンマ区切りのパラメータを受け入れる配列パラメータを指定できます。
パラメータには、予約語ではない名前を指定することができます。
このパラメータ宣言は、指定される最後のパラメータである必要があります。
このパラメータを使用すると、 arguments オブジェクトにアクセスできなくなります。
… (rest) パラメータには arguments 配列および arguments.length プロパティと同じ機能がありますが、 arguments.callee のような機能はありません。
… (rest) パラメータを使用する前に、arguments.callee を使用する必要はありません。
… (rest) の (rest) の部分は予約語以外なら好きに命名してよい。
[as3]function traceArgArray(… args):void{
for (var i:uint = 0; i < args.length; i++) { trace(args[i]); } } traceArgArray(1, 2, 3); // output: // 1 // 2 // 3[/as3] この方法なら、呼び出し時に設定する引数の個数が可変になる。
1つの関数で、場合によっては引数3つ、別の場合は5つなんていうことが可能。
つまり、引数の個数が可変なのだ。
すごいなぁ。
もちろん一括処理も可能。
[as3]function traceArgArray(x: int, … args)
{
for (var i:uint = 0; i < args.length; i++)
{
trace(args[i]);
}
}
traceArgArray(1, 2, 3);
// output:
// 2
// 3[/as3]
このように固定された引数があっても大丈夫。
但し、...(rest) パラメータは必ず最後の引数とすること。
arguments オブジェク | …(rest) パラメータ | |
---|---|---|
引数全てを含む配列 | オブジェクト | 固定引数以外を含む配列 |
不要 | 明示 | 引数欄の末尾 |
を持つ | callee プロパティ | 持たない |