小池啓仁 ヒロヒト応援ブログ By はてな

小池啓仁(コイケヒロヒト)の動画など。

小池啓仁 ヒロヒト応援ブログ By はてな

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さんに『サブルーチンの頭に&は普通つけない』と教えて頂いたのですが・・・。

組み込み関数と同名のユーザ定義関数を定義したときは、どうしても『&』付きでないと呼び出せないのです。
また、現在、組み込み関数と同名がないユーザ定義関数を作って『&』無しで呼んで上手くいっていても、将来、同名の組み込み関数が出来る可能性もあるわけです。
すると、ユーザ定義関数でなく、組み込み関数が呼ばれるようになり、上位互換性がなくなり・・・。
なのでユーザ定義関数は、『&』をつけたほうがよいと思うのです。どうでしょうか?


『&』は、基本的につけません。これに関しては以下のリンク先を参照願います。

また、id:miyagawa氏から、以下のようなコメントも頂きました。

将来組み込み関数が増えた場合でも、それらの関数は use feature しないと有効にならない仕組みになっている(5.10のsay や givenなど) ので、何もなしに動かなくなる、ということはないはず。

◆ 結論

  • 組み込み関数をコールする時は、小カッコ『()』を付けない。
  • ユーザ定義関数をコールする時は、小カッコ『()』を付ける。しかし、『&』は付けない。

結局、前にbingo_nakanishさんに教えて頂いた通りでした(^o^)