Perl Language
サブルーチン
サーチ…
備考
サブルーチンは@_
という魔法の変数に引数を@_
ます。解凍する必要はありませんが、読みやすいようにすることをお勧めします。また、 @_
引数が参照渡し(変更可能)で誤った変更を防ぐことができます。
サブルーチンの作成
サブルーチンはキーワードsub
後に識別子と中括弧で囲まれたコードブロックを使用して作成されます。
すべての引数を配列として含む特殊変数@_
を使用して、引数にアクセスできます。
sub function_name {
my ($arg1, $arg2, @more_args) = @_;
# ...
}
機能のでshift
シフトデフォルト@_
サブルーチン内で使用される場合には、サブルーチンの開始時にローカル変数に順次引数を抽出する一般的なパターンです。
sub function_name {
my $arg1 = shift;
my $arg2 = shift;
my @more_args = @_;
# ...
}
# emulate named parameters (instead of positional)
sub function_name {
my %args = (arg1 => 'default', @_);
my $arg1 = delete $args{arg1};
my $arg2 = delete $args{arg2};
# ...
}
sub {
my $arg1 = shift;
# ...
}->($arg);
あるいは、実験的特徴"signatures"
を使用して、値によって渡されるパラメータ(参照ではない )をアンパックすることができる。
use feature "signatures";
sub function_name($arg1, $arg2, @more_args) {
# ...
}
パラメータにはデフォルト値を使用できます。
use feature "signatures";
sub function_name($arg1=1, $arg2=2) {
# ...
}
任意の式を使用して、他のパラメータを含むパラメータにデフォルト値を与えることができます。
sub function_name($arg1=1, $arg2=$arg1+1) {
# ...
}
現在のパラメータの後に定義されたパラメータは参照できないため、次のコードは期待どおりに機能しません。
sub function_name($arg1=$arg2, $arg2=1) {
print $arg1; # => <nothing>
print $arg2; # => 1
}
サブルーチンの引数は参照によって渡されます(シグネチャの引数を除く)
Perlのサブルーチン引数は、署名に含まれていない限り、参照渡しされます。つまり、サブ配列の@_
配列のメンバーは実際の引数のエイリアスに過ぎません。次の例では、サブプログラム内の$_[0]
は実際には同じ変数の別の名前なので、メインプログラムの$text
はサブルーチンコールの後に変更されたままになります。 2番目の呼び出しは、文字列リテラルが変数ではないため、変更できないため、エラーが発生します。
use feature 'say';
sub edit {
$_[0] =~ s/world/sub/;
}
my $text = "Hello, world!";
edit($text);
say $text; # Hello, sub!
edit("Hello, world!"); # Error: Modification of a read-only value attempted
コピーすることが重要である、あなたの呼び出し側の変数をつかう避けるために@_
ローカル(変数のスコープにmy ...
)「の作成サブルーチン」で説明したよう。
サブルーチン
サブルーチンはコードを保持します。特に明記されていない限り、それらはグローバルに定義されています。
# Functions do not (have to) specify their argument list
sub returns_one {
# Functions return the value of the last expression by default
# The return keyword here is unnecessary, but helps readability.
return 1;
}
# Its arguments are available in @_, however
sub sum {
my $ret = 0;
for my $value (@_) {
$ret += $value
}
return $ret;
}
# Perl makes an effort to make parens around argument list optional
say sum 1..3; # 6
# If you treat functions as variables, the & sigil is mandatory.
say defined ∑ # 1
print
やsay
ような組み込み関数はキーワードであり、関数ではないので、 &say
は定義されていません。また、定義することもできますが、実際に呼び出すにはパッケージ名を指定する必要があります
# This defines the function under the default package, 'main'
sub say {
# This is instead the say keyword
say "I say, @_";
}
# ...so you can call it like this:
main::say('wow'); # I say, wow.
Perl 5.18以来、非グローバル関数を持つこともできます:
use feature 'lexical_subs';
my $value;
{
# Nasty code ahead
my sub prod {
my $ret = 1;
$ret *= $_ for @_;
$ret;
}
$value = prod 1..6; # 720
say defined ∏ # 1
}
say defined ∏ # 0
5.20以降、名前付きパラメータを持つこともできます。
use feature 'signatures';
sub greet($name) {
say "Hello, $name";
}
これをプロトタイプと混同してはいけません 。Perlは組み込み関数のように振る舞う関数を定義できるようにしなければなりません 。関数プロトタイプはコンパイル時に可視でなければならず、その効果は&
sigilを指定することによって無視することができます。プロトタイプは、一般的に、細心の注意を払って最もよく使用される高度な機能であると考えられています。
# This prototype makes it a compilation error to call this function with anything
# that isn't an array. Additionally, arrays are automatically turned into arrayrefs
sub receives_arrayrefs(\@\@) {
my $x = shift;
my $y = shift;
}
my @a = (1..3);
my @b = (1..4);
receives_arrayrefs(@a, @b); # okay, $x = \@a, $y = \@b, @_ = ();
receives_arrayrefs(\@a, \@b); # compilation error, "Type … must be array …"
BEGIN { receives_arrayrefs(\@a, \@b); }
# Specify the sigil to ignore the prototypes.
&receives_arrayrefs(\@a, \@b); # okay, $x = \@a, $y = \@b, @_ = ();
&receives_arrayrefs(@a, @b); # ok, but $x = 1, $y = 2, @_ = (3,1,2,3,4);