Perlの謎(その10)サブルーチンの呼び出し方
予告したサブルーチンの呼び出し方の謎です。
しかし、予告した割りには、上手くまとまらなかったのですが・・・以下のようになりました。
◆ イントロ
まず、Perlでのサブルーチンは関数と等価です。
そして、関数の呼び出し方には、『&』のファニー文字を付けたり、付けなかったり・・・。
また、関数名の後に『()』小カッコを付けたり、付けなかったり・・・。
またまた、『&』も『()』も付けなく、ベアワードになったりと・・・。
これらは、『組み込み関数やインポートしたモジュール関数』と『ユーザ定義関数』で意味が違ってきます。
なので、各々について対比して解説をしてみました。
尚、以下は、あくまでも私のコーディング方針で、強制的なものではありません。
◆ 『&』ファニー文字について
組み込み関数やインポートしたモジュール関数は、『&』ファニー文字は付けない。
組み込み関数等に『&』を付けるとエラーになる。(ユーザ定義関数を探しに行ってエラーとなる)
ユーザが定義できる関数(サブルーチン)は、『&』を付ける方がよい。
これは、ユーザ定義関数でも『&』を付けないで呼び出せますが、同名の組み込み関数等がある場合、組み込み関数が優先され、ユーザ定義関数は無視されます。なのでユーザ定義関数は『&』を付ける方がよい。
いろいろな理由で『&』を付けず、ユーザ定義関数は関数名の後に『()』小カッコを付ける方がよい。
しかし、万が一、組み込み関数とユーザ定義関数が同名になった時は、『&』でユーザ定義関数を呼び出すことができる。
use strict; use warnings; my $hoge1 = time; # 組み込み関数 my $hoge2 = &time; # ユーザ定義関数 print $hoge1 , "\n"; print $hoge2 , "\n"; sub time { return 'hoge'; }
◆ 関数名の後の『()』小カッコについて
組み込み関数やインポートしたモジュール関数は、『()』小カッコを付けない方がよい。
カッコを付けてもOKですが、ユーザ定義関数以外であることを明示するために『()』を付けない方がよい。
ユーザが定義できる関数(サブルーチン)は、『()』小カッコを付ける。
関数をロジックの前置きに定義すると、カッコなしでもOKですが、そうしない。『()』小カッコを付けてユーザ定義関数を明示する。
use strict; use warnings; my $hoge1 = localtime time; # 組み込み関数 my $hoge2 = &localtime(time); # ユーザ定義関数 print $hoge1 , "\n"; print $hoge2 , "\n"; sub localtime { return $_[0]; }
◆ 引数のない関数について
引数のない場合の組み込み関数やインポートしたモジュール関数は、ベアワードにする。
引数のない場合のユーザが定義できる関数(サブルーチン)は、『&』『()』を付ける方がよい。
◆ ユーザ定義関数は、『&』をつけない?
前に、bingo_nakanishさんに『サブルーチンの頭に&は普通つけない』と教えて頂いたのですが・・・。
- サブルーチンの頭に&は普通つけない
http://d.hatena.ne.jp/bingo_nakanishi_perl/20090618/1245326468
組み込み関数と同名のユーザ定義関数を定義したときは、どうしても『&』付きでないと呼び出せないのです。
また、現在、組み込み関数と同名がないユーザ定義関数を作って『&』無しで呼んで上手くいっていても、将来、同名の組み込み関数が出来る可能性もあるわけです。
すると、ユーザ定義関数でなく、組み込み関数が呼ばれるようになり、上位互換性がなくなり・・・。
なのでユーザ定義関数は、『&』をつけたほうがよいと思うのです。どうでしょうか?
『&』は、基本的につけません。これに関しては以下のリンク先を参照願います。
- & はいつ使うべきか http://blog.livedoor.jp/dankogai/archives/51237271.html
- 関数と演算子 http://d.hatena.ne.jp/deq/20061213/1165991932
また、id:miyagawa氏から、以下のようなコメントも頂きました。
将来組み込み関数が増えた場合でも、それらの関数は use feature しないと有効にならない仕組みになっている(5.10のsay や givenなど) ので、何もなしに動かなくなる、ということはないはず。
◆ 結論
- 組み込み関数をコールする時は、小カッコ『()』を付けない。
- ユーザ定義関数をコールする時は、小カッコ『()』を付ける。しかし、『&』は付けない。
結局、前にbingo_nakanishさんに教えて頂いた通りでした(^o^)