[Perl] 文法:変数(文字列、配列、ハッシュ) - lot36z/perl_wiki GitHub Wiki
変数の種類
Perlのコメントは#以降の文字列全て。 変数は3種類あり、変数名の頭に記号をつけて区別する。
# スカラ(数値、文字列など)
$変数名
# 配列
@変数名
# ハッシュ
%変数名
変数宣言
my $変数名;
変数宣言&初期化
my $変数名 = 値;
my ではなく our を使うと、グローバル変数になる。
文字列
文字列の定義方法
文字列は、文字列をシングルクォーテーションまたはダブルクォーテーションで囲むことで定義できる。
e.g. 文字列の変数宣言と初期化
my $string1 = '文字列1';
my $string2 = "文字列2";
シングルクォーテーションでは、中身の文字はそのまま文字列とみなされる。 一方で、ダブルクォーテーションでは、中身の文字の中に$で始まる変数が含まれていると、その変数を文字列に展開した後の文字列を最終的な文字列とみなす。
e.g. シングルクォーテーションとダブルクォーテーションで文字列を定義した時の違い
my $string = 'This is my string.';
my $single_quotated_str = '$string'; # シングルクォーテーションを使用。$stringは展開されない。
my $double_quotated_str = "$string"; # ダブルクォーテーションを使用。$stringは展開され、This is my string.になる。
print $single_quotated_str;
print "\n"; # 改行する。
print $double_quotated_str;
# [output]
# $string
# This is my string.
文字列のエスケープ処理
シングルクォーテーションを使う場合
文字列をシングルクォーテーションを使って定義する場合、シングルクォーテーション自体も文字列の中に入っていると、 Perlはうまくそれらを区別できない。
e.g. シングルクォーテーションの誤った使い方
my $string = 'I don't like single quotations.';
Perlは'I don'までを文字列の定義部分とみなすので、コンパイルエラーが出てしまう。
このように、シングルクォーテーションの中でシングルクォーテーションを使いたい時には、 バックスラッシュ\でエスケープする必要がある。
e.g. シングルクォーテーションを正しくエスケープした使い方
my $string = 'I don\'t like single quotations.';
print $string;
# [output]
# I don't like single quotations.
ダブルクォーテーションを使う場合
文字列をダブルクォーテーションを使って定義する場合、ダブルクォーテーション自体、または変数ではない$が文字列に入っていると、 Perlはそれらを正しく解釈できない。
e.g. ダブルクォーテーションと$の誤った使い方
my $string = "Definition: $b means "book title" and $a means "author"";
Perlは$bと$aを変数として解釈し展開しようとするが、 変数$bも$aも定義されていないので、コンパイルエラーが出てしまう。 また、Perlは"Definition: $b means "までを文字列の定義部分とみなすので、コンパイルエラーが出てしまう。
e.g. ダブルクォーテーションと$を正しくエスケープした使い方
my $string = "Definition: \$b means \"book title\" and \$a means \"author\"";
print $string;
# [output]
# Definition: $b means "book title" and $a means "author"
変数展開以外にも、バックスラッシュ\の後ろに決まった文字があると、 Perlはそれを解釈して特殊な展開を行う。
リファレンスを使った統一的な変数の取り扱い
個人的には、配列もハッシュも、「リファレンス」としてスカラ変数と同じように、
$変数名
に格納するよう統一するのが便利。
こうすると、配列のリファレンスは[]で定義し、
ハッシュのリファレンスは{}で定義できるので、Pythonなど他の言語と近い文法で定義できる。
また、多次元配列や配列とハッシュが複雑に入れ子になった配列やハッシュも違和感なく使えるようになる。
e.g. 配列をリファレンスとして保持し、リファレンスから配列の要素を取得。
my @array = (1,2,3); # 配列の宣言&初期化
my $ref = \@array; # \演算子で配列のリファレンスを取得して変数$refに格納。
my $element = $ref->[0]; # ->[0]で、配列のリファレンスから0番目の要素を取得。
print $element;
# [output]
# 1
e.g. ハッシュをリファレンスとして保持し、リファレンスからハッシュの特定のキーのバリューを取得。
my %hash = ('author' => 'Natsume Soseki', 'title' => 'Kokoro'); # ハッシュの宣言&初期化
my $ref = \%hash; # \演算子でハッシュのリファレンスを取得して変数$refに格納。
my $value = $ref->{'title'}; # ->{'title'}で、ハッシュのリファレンスからキー'title'に対するバリューを取得。
print $value;
# [output]
# Kokoro
e.g. スカラの初期化と出力
my $var = 2;
print $var;
# [output]
# 2
e.g. 配列の初期化と出力
my $array = [1,2,3]; # 配列をいきなりリファレンスとして宣言&初期化
foreach my $each (@$array)
{
# リファレンスから順次、配列の要素を取得。
# 配列のリファレンスの頭に@を付けることで、配列を取得できる。
print "$each\n";
}
# [output]
# 1
# 2
# 3
my $array=[1,2,3];
for(my $i; $i< scalar(@$array); $i++)
{
# scalar関数により、配列の要素数を取得できる。
my $each = $array->[$i];
print "$each\n";
}
# [output]
# 1
# 2
# 3
e.g. ハッシュの初期化と出力
my $hash = {'author' => 'Natsume Soseki', 'title' => 'Kokoro'}; # ハッシュをいきなりリファレンスとして宣言&初期化
foreach my $key (keys(%$hash))
{
# keys関数により、ハッシュの全てのキーを配列として取得できる。
# リファレンスから順次、ハッシュのキーに対応するバリューを取得。
# ハッシュのリファレンスの頭に%を付けることで、ハッシュを取得できる。
print "$key:";
my $value = $hash->{$key};
print "$value\n";
}
# [output]
# author:Natsume Soseki
# title:Kokoro
e.g. 2次元配列
my $array =
[
[ 11, 12, 13 ],
[ 21, 22, 23 ]
];
foreach my $each (@$array)
{
foreach my $element (@$each)
{
print "$element\n";
}
}
# [output]
# 11
# 12
# 13
# 21
# 22
# 23
e.g. 本のリスト
my $book_list =
[
{
'title' => 'Kokoro',
'author' => 'Natsume soseki'
},
{
'title' => 'Kumo no Ito',
'author' => 'Akutagawa Ryunosuke'
}
];
foreach $book (@$book_list)
{
foreach $key (sort(keys(%$book)))
{
# sort関数を使うと、配列の値が昇順でソートされる。
my $value = $book ->{$key};
print "$key:";
print "$value\n";
}
print "\n"; # 空行
}
# [output]
# author:Natsume soseki
# title:Kokoro
#
# author:Akutagawa Ryunosuke
# title:Kumo no Ito
#