前回の
よくある質問への回答
ここでは,
変数名の左にある記号がコロコロ変わって理解できない
Perlには,$
,@
,%
がシジルとして変数名の前に付きます。同じ変数名であっても,
シジルが$
のスカラは,
シジルが@
の配列とシジルが%
のハッシュは,$
に変化します。サブルーチンの戻り値として配列を受け取るときは,@
の配列に代入します。ハッシュリファレンスをデリファレンスしたものは,%
のハッシュに代入します。
自分が操作したい対象を意識できると理解が進み,
配列とハッシュを使い分けられない
初学者であっても,
配列は,
array_sample.pl
# 配列によるデータ管理例:出席番号順生徒名簿
my @members = ('Alice', 'Bob', 'Carol', 'Dave');
# 順番に表示する
for my $member (@members) {
print "name: $member\n";
}
ハッシュは,
hash_sample.pl
# ハッシュによるデータ管理例:テストの成績管理
my %score = (Japanese => 75, English => 80);
# 英語の点数を表示
print "English score: $score{English}\n";
配列とハッシュそれぞれの特徴を把握すると,
初歩的文法を理解できているか不安
15年ほど前に話題になったFizzBuzz問題を解いてみましょう。
1から100までの数をプリントするプログラムを書け。ただし3の倍数のときは数の代わりに
「Fizz」 と, 5の倍数のときは 「Buzz」 とプリントし, 3と5両方の倍数の場合には 「FizzBuzz」 とプリントすること。
── Jef Atwood著/
この問題を解くためには,if
文),for
文)
fizzbuzz.pl
# 配列の使用
my @numbers = (1 .. 100);
# for文による繰り返し処理。変数へ値の格納
for my $num (@numbers) {
# if文による条件分岐処理
if ( $num % 3 == 0 && $num % 5 == 0 ) {
print 'FizzBuzz' . "\n";
} elsif ( $num % 3 == 0 ) {
print 'Fizz' . "\n";
} elsif ( $num % 5 == 0 ) {
print 'Buzz' . "\n";
} else {
print $num . "\n";
}
}
このFizzBuzz問題をスムーズに解ければ,
リファレンスを使う理由がわからない
受講生から,
Perlのスカラには1つの値しか代入できません。配列やハッシュの要素として,
リファレンスは,
data_struct.pl
# リファレンスを利用し,複雑なデータ構造を扱う
my %person1 = (
name => 'xtetsuji',
mail => 'xtetsuji@example.com'
);
my %person2 = (
name => 'sironekotoro',
mail => 'sironekotoro@example.com'
);
my %person3 = (
name => 'tomcha',
mail => 'tomcha@example.com'
);
my @people = ( \%person1, \%person2, \%person3 );
# 情報を一覧表示する
for my $person (@people) {
my $name = $person->{name};
my $mail = $person->{mail};
print "$name さんのメールアドレスは $mail です\n";
}
リファレンスを使う理由を理解し,
変数の中身が意図しない値になる
変数に格納された数値や文字列をコピーしてほかの変数へ渡した場合,
それに対してリファレンスをコピーしてほかの変数へ渡した場合,
値渡しと参照渡しの違いは,
reference_data_change.pl
# 値渡し時の挙動
my $number1 = 10;
my $number1_dup = $number1; # コピーを代入
$number1_dup *= 100;
print "もとのデータ: $number1\n"; # => 10
print "渡し先のデータ: $number1_dup\n"; # => 1000
# 参照渡し時の挙動
my $number2 = 10;
my $number2_ref = \$number2; # リファレンスを代入
$$number2_ref *= 100;
print "もとのデータ: $number2\n"; # => 1000
print "渡し先のデータ: $$number2_ref\n"; # => 1000
値渡し時のコードでは,$number1_
に加えた変更は,$number1
の値には影響しません。参照渡しのコードでは,$number2_
に加えた変更が,$number2
の値にも適用されます。
値渡しと参照渡しの特徴を理解して使い分けましょう。
- 注1)
- Perlのリファレンスを渡す手法は,
正しくは参照の値渡しと呼びます。