TOP > スクリプト制作メモ > Perlの変数について

≫序章

変数とは、数学で習う X や Y と似たようなもので、情報の入れ物です。ただ、入れる情報によって型と呼ばれるものが変ってきます。例えば、数値を入れておくのと文字列を入れておくのとでは多少扱いが変ります。プログラミングに取り組み始めの頃はこの辺につまづきやすいのですが、慣れれば屁の様なもんです(^_^;)

しかも、Perl は数値だろうが文字列だろうが同じに扱える、すげーダイナミックな言語です。詳しくは後ほど述べていくとして、変数の扱いを色々知っていくと、いままで複雑な処理にしてしまいがちだったところを簡潔にコード化できたりします。

そういうわけで、変数についてざっくり解説してみようかと思います。

参考:楽:勝手Perlリファレンス/変数について

≫スカラー変数ついて

スカラー変数は最も基本的な変数です。

   $hoge = 7;
   $page = "www.bayashi.net";

以上の様な使われ方をします。$hoge や $page がスカラー変数で、7 や " (ダブルクオート)で囲まれた部分が変数の値となります。

変数は $ が頭につき、変数名には英数字とアンダーバーが使えます。ただし、数字やアンダーバーが $ の直後に来るのはオススメできません。

変数に値を代入する場合、数値(半角)ならそのままで OK ですが、文字列の場合はクオートで囲まなければなりません。

   $hoge = "www.bayashi.net";
   $hoge = 'www.bayashi.net';

ダブルクオートでもシングルクオートでも基本的には同じですが、代入する文字列自体にダブルクオートやシングルクオートがある場合や特殊な記号が含まれる場合、エスケープする必要がでてきます。また、ダブルクオート内の変数は展開されて代入されますが、シングルクオート内の変数はただの文字列扱いとなります。

   $a = "abc";
   $hoge = "123$a";
   $page = '123$a';

   print "hoge = $hoge : page = $page";

   出力結果 hoge = 123abc : page = 123$a

ヒアドキュメントと呼ばれる以下のような代入の仕方もあります。

   $hoge = <<"_HTML_";
   www.bayashi.net
   _HTML_

ヒアドキュメントの場合も "_HTML_" の囲みがダブルクオートであるかシングルクオートであるかによってエスケープしなければならない記号や変数の展開に差があります。

≫配列変数について



 配列変数とはスカラー変数に添字をつけて、連続した変数を一式で扱える便利な変数です。

   1 愛川
   2 今井
   3 宇多田
   4 江川
   5 岡林

というリストがあった場合、

   $name1 = "愛川";
   $name2 = "今井";
   $name3 = "宇多田";
   $name4 = "江川";
   $name5 = "岡林";

という風に、ひとつづつスカラー変数にするよりも

   $name[1] = "愛川";
   $name[2] = "今井";
   $name[3] = "宇多田";
   $name[4] = "江川";
   $name[5] = "岡林";

という風に、配列変数にした方がなにかと便利です。

配列変数は、スカラー変数のデータ構造違いで、頭に @ をつけます。従って前述したリストの変数全体をあらわす場合は、

   @name

となります。それぞれの要素を表す時は $name[n] という形になるのですね。[n] の添え字は [ ] で囲みます。添え字の数字は 0 からはじまります。

前述の5つの要素を定義するには以下のように書くことも出来ます。

   @name = ("愛川","今井","宇多田","江川","岡林");

他にも、配列変数にはいろいろと面白い記述方があります。

表現解説
@hoge配列変数 @hoge 全体
$hoge[3]配列変数 @hoge の4番目の要素
$hoge[-1] 配列変数 @hoge の最後の要素
$#hoge配列変数 @hoge の最後の添字番号(添字は 0 から始まるので要素の数より 1 少ない値になります)。
$page = @hoge;スカラー変数に配列変数を代入すると要素数が代入されます。
$#hoge = -1;
@hoge = ();
どちらも @hoge を空にします。
undef @hoge;@hoge を未定義値にします。


   @name = ("愛川","今井","宇多田","江川","岡林");

   print @name;
   出力結果 愛川 今井 宇多田 江川 岡林

   print $name[2];
   出力結果 宇多田

   print $name[-1];
   出力結果 岡林

   print $#name;
   出力結果 4

   $a = @name;
   print $a;
   出力結果 5


さて、連想配列なんですが、ここまで説明したような1次元のものだけでなく、2次元や3次元のものもあります。

   $name[0][0] = "愛川";
   $name[0][1] = "今井";
   $name[1][0] = "赤坂";
   $name[1][1] = "石田";


   $color[0][0][0] = "シアン";
   $color[0][0][1] = "マゼンタ";
   $color[0][1][0] = "イエロー";
   $color[0][1][1] = "クロ";


ただ、Perl に限れば下で説明する連想配列の方が便利なので、多次元の配列変数を使う機会は少ないかもしれません。

配列変数を扱うための関数は以下の様なものがあります。

関数名解説
unshift 配列の先頭に要素を追加する。
unshift(@hoge,"abc");
push 配列の末尾に要素を追加する。
push(@hoge,"abc");
shift 配列の先頭の要素を取り除く。
$str = shift @hoge;
pop 配列の末尾の要素を取り除く。
$str = pop @hoge;
splice 配列の要素を任意の位置で削除/追加します。
splice(@hoge,-1);
sort リストをソートします。
sort @hoge;
sort {$a <=> $b} @hoge; # 数値昇順ソート
sort {$a cmp $b} @hoge; # 文字列の昇順ソート
reverse リスト値を逆順に並び替える。
@page = reverse @hoge;
split 文字列を分割する。
@hoge = split(/\t/,$str);
join 区切り文字列を挟んで文字列を連結します。
$str = join("\t",@hoge);
grep 要素を評価し、真になった要素を返す。
@page = grep(/^a/,@hoge);
map 要素を評価し、結果を返します。
map{ s/abc/def/ } @hoge;

≫連想配列変数について

連想配列とは通常の配列変数のように数値が添え字にくるのではなく、文字列を添え字として使える配列変数です。ハッシュとか呼ばれたりもします。

一般的な掲示板やチャットなどのCGIで GET もしくは POST で受け取ったデータを格納しておく際によく利用されています。
以下の様なルーチンはよく見かけると思います。

   read(STDIN,$buffer,$ENV{'CONTENT_LENGTH'});
   @pairs = split(/&/,$buffer);
   foreach $pair (@pairs){
    ($name,$value) = split(/=/,$pair);
    $value =~ tr/+/ /;
    $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("H2",$1)/eg;
    &jcode'convert(*value,'euc');
    $value =~ s/\x0D\x0A/\r/g;
    $FORM{$name} = $value;
   }

この $FORM{$name} が連想配列変数です。連想配列全体を表す時には %FORM となります。ちなみに、FORM はただの変数名です。一般的に連想配列変数名は大文字で記述することが多いようです。

$FORM{$name} の $name をキーと言います。キーは英数字だけでなく漢字も使えます。

   $HOGE{'black'} = '#000000';
   $HOGE{'white'} = '#FFFFFF';

各要素は上のように定義できます。
'black' のシングルクオートはダブルクオートでもかまいません。ただし、変数の展開がある場合はダブルクオートでないといけません。また、クオートで囲まず直接キー文字列を書く記述法( $HOGE{black} = '#000000'; )は Perl5 以上でないと使えません。

表現解説
%HOGE連想配列変数 %HOGE 全体
$HOGE{'page'}連想配列変数 %HOGE の 'page'をキーとする要素
%HOGE = ('key'=>'value');$HOGE{'key'} = 'value';と同列
%HOGE = ();%HOGE を空にします。
undef %HOGE;%HOGE を未定義値にします。
$a = scalar keys %HOGE;%HOGE の要素数を求めます。


連想配列はキーが文字列であり、その順序は保障されていません。したがって、連想配列 %HOGE の最初の要素や最後の要素といった概念がありません。定義した順序も関係ありません。

ただ、スクリプトを組んでいく上ではキーを一定にソートした順で取り出したいことがあると思います。 そういう場合は以下の様にします。

   foreach $loop (sort { $IN{$b} <=> $IN{$a} } keys %IN){
     ……処理……
   }

%IN のキーを取り出し、ソートして foreach を繰り返します。

keys というのはハッシュのキーを取り出す関数です。{ $IN{$b} <=> $IN{$a} } はソートを文字コード順にするための記述です。

ハッシュを扱うための関数は以下の様なものがあります。

関数名解説
delete ハッシュから指定したキーとその値を削除する。
delete %HOGE{'key'};
each ハッシュからキーとその値を取り出す。
($key,$value) = each %HOGE;
exists ハッシュに指定したキーが存在すれば真を返す。
if(exists $HOGE{'key'}){ delete $HOGE{'key'}; }
keys ハッシュ内の全てのキーを取り出す。
@keylist = keys %HOGE;
values ハッシュ内の全ての値を取り出す。
@valuelist = value %HOGE;
■ちょっとコラム 〜変数のクリア〜

スカラー変数を未定義値に戻すには

   undef($hoge);

とします。

   $hoge = '';

これは、スカラー変数にNull(ヌル)を代入しています。

このふたつの違いは、 undef はメモリ上もクリアされますが、Null を代入してもメモリ領域上は確保されたままです。

   $hoge = '123abc';
   $hoge = '';

という流れの場合、$hoge = ''; と変数の中身はなくなってもメモリ領域上は '123abc' が代入された時のままです。

ちなみに、配列変数や連想配列は undef すると変数全体が未定義値となります。

   undef(@hoge);

   undef(%HOGE);

例えば、以下の様にすると、ひとつだけ未定義値に出来そうですが動作的には全体が未定義値になります。

   undef($hoge[3]);

   undef($HOGE{'page'});

個々の要素と値を削除するには、連想配列の場合は delete という関数が用意されています。配列変数の場合は shift や pop といった関数があります。

≫連想配列の連想配列

連想配列の連想配列。言いかえればハッシュのハッシュ。2次元配列変数の連想配列版と思ってください。けっこう扱いがややこしくなるのですが、ここぞという使い道は意外に多いかも知れません。

   %HOGE = ('Comic' => {'夢の温度' => '南Q太', 'バガボンド' => '井上雄彦'});

   print $HOGE{'Comic'}{'バガボンド'};

   出力結果:井上雄彦

一番シンプルな感じですが、理解できますでしょうか。

全要素と値の出力ループは以下のようになります(書き方は色々ですが)。

   foreach $firstkey (keys %HOGE){
     print "<b>$firstkey:</b><br>";
     foreach $secondkey (keys %{$HOGE{$firstkey}}){
       print "$secondkey = $HOGE{$firstkey}{$secondkey}<br>";
     }
     print "<br>\n";
   }

≫連想配列をサブルーチンに渡す

Perl のサブルーチンに引数を渡す際は、スカラーのリストでなければならない。
my $str = &NantokaSub('Scalar1','Scalar2');

sub NantokaSub {
my $str1 = shift;
my $str2 = shift;
return "$str1$str2";
}
とか
my $str = &NantokaSub('Scalar1','Scalar2');

sub NantokaSub {
my @Strs = @_;
return "$Strs[0]$Strs[1]";
}
連想配列変数を、サブルーチンに渡す場合はどうするか。

リファレンスというものを利用します。

リファレンスというのは、変数がどこにあるかを示す値のようなものです。

リファレンスは、変数の前に \ を付けて取得します。
my %EXAMPLE;
my $ref_exampl = \%EXAMPLE;
リファレンスをサブルーチンに渡すことで、変数の実体をやり取りせずに、メインルーチンとサブルーチンで同じ変数にアクセスすることを実現します。
my %EXAMPLE;
$EXAMPLE{'test'} = "TEST";
my $ref_exampl = \%EXAMPLE;
&NantokaSub($ref_exampl);

sub NantokaSub {
my $str = shift;
print $$str{'test'};
print "\n";
print $str->{'test'};
return;
}
$$str{'test'} と $str->{'test'} は同じ意味で、ともに、メインルーチンの $EXAMPLE{'test'} を指します。


TOP > スクリプト制作メモ > Perlの変数について
(C) bayashi.net