東京工業大学大学院理工学研究科基礎物理学専攻中村研究室メンバー

ホームページおぼえがき > Perl

Perl

Perlのおぼえがき。Debina etchで動かし中。

(制作中。わからないところ多し。間違いが有る可能性大。)

Perlについて

長所
短所

コーディングのきまり

■ 大文字/小文字

Perlでは、大文字と小文字の区別がある。

$para = "aa";     # この3つの変数 $para, $Para, $PARAは違うもの。
$Para = "bb";     #
$PARA = "cc";     #

■ コメント

# の右がコメントとみなされる。

#     ここはコメント
$para = 1      # ここもコメント

■ 1行の文字数

1行の文字数は無制限?プログラムは一行目以外改行しなくてもいいかも?でも見にくい。

#!/usr/bin/perl
$para1 = "aa"; $para2 = "bb"; print "$para1$para2\n"; exit;

■ Hello World!!

Hello World!!を表示する。

ファイル名: hello.pl
#!/usr/bin/perl

print "Hello World!!\n";

exit;

上記の内容のファイルを保存したら、端末でhello.plのあるディレクトリに移動し、以下のコマンドを実行。

$ chmod u+x hello.pl     # 実行権限を追加。
$ ./hello.pl             # 実行。
Hello World!!

メモ1) \nは改行を表す。

メモ2) プログラム一行目の #!/usr/bin/perl はコードを解釈するプログラム(インタープリター)であるperlがある場所を示している。この行を書かないとエラーになる。perlのある場所の確認は、以下のコマンドを実行。

$ which perl
/usr/bin/perl

以下の方法でもHello World!!できる。

ファイル名: hello2.pl
print "Hello World!!\n";
exit;

上記の内容のファイルを保存したら、端末でhello2.plのあるディレクトリに移動し、以下のコマンドを実行。

$ perl hello2.pl     # 実行。
Hello World!!

変数

■ 変数の種類

変数は主に三種類。スカラー変数と、配列変数、連想配列変数。

$par = "aa";                            # スカラー変数 $par に文字列 aa を代入。
@arr = ("aa", "bb", "cc");              # 配列変数 @arr に3つの文字列を代入。
%ass = ("key1"=>"val1","key2"=>"val2"); # 連想配列 %ass にkey1とval1、key2とval2をセットにして代入。

変数の中身を見るときは、以下のようにする。

ファイル名: test1.pl
#!/usr/bin/perl

$par = "aa";
@arr = ("aa", "bb", "cc");
%ass = ("key1"=>"val1", "key2"=>"val2");

print "$par\n";           # $par の中身"aa"を表示。\nは改行を表す。
print "@arr\n";           # @arr の中身"aa bb cc"を全部表示。
print "$arr[0]\n";        # @arr の0番目の要素"aa"を表示。
print "$arr[1]\n";        # @arr の1番目の要素"bb"を表示。
print "$arr[2]\n";        # @arr の2番目の要素"cc"を表示。
print "$ass{"key1"}\n";   # %ass の"key1"に対する値"val1"を表示。

exit;
実行結果
$ chmod u+x test1.pl
$ ./test1.pl
aa
aa bb cc
aa
bb
cc
val1

■ 変数の宣言

Perlでは、変数の宣言はしなくても良い。また、整数型、実数型、文字列型の違いがあいまい?変数は時と場合により、整数、実数、文字列を格納する。よって、変数の型が変わるように見える。

ただし、use strict;を書いたときは、宣言が必要。

■ 使用可能な変数名

変数名の頭文字はa〜zとアンダーバー(_)が使える。頭文字以外は、数字やアンダーバー(_)が使える。

$season        ! OK
$spring_8      ! OK
$autumn2winter ! OK
$_summer       ! OK
$4seasons      ! NG

変数名は割りと長くても大丈夫かも。100文字の変数名が使えた。

スカラー変数

■ 代入

スカラー変数には、整数、実数、文字列などの異なる型のものを格納できる。

$par1 = 100;              # スカラー変数 $par1 に整数 100 を代入。
$par2 = 3.1415;           # スカラー変数 $par2 に実数 3.1415 を代入。
$par3 = "aa";             # スカラー変数 $par3 に文字列 aa を代入。

スカラー変数の型は演算により変わる。

$par1 = 100;
$par2 = 3.1415;
$par3 = "aa";

$par1 = $para1 * 2.7182;  # $par1 に 実数 271.82 が代入される。
$par2 = 50;               # $par2 に 整数 50 が代入される。
$par3 = $para3 . "bb";    # $par3 に 文字列 aabb が代入される。 「.」は文字列を結合させる演算子。
$par3 = $par1 . $para2;   # $par3 に 文字列 271.8250 が代入される。

■ 文字列の表し方

文字列の表し方にもいろいろある。

$par1 = "aa";             # 文字列をあらわすには、ダブルクオートを用いる。
$par2 = 'bb';             # シングルクオートでもよい。

$par3 = 'string "aa"';    # ダブルクオート自身をあらわすには、シングルクオートの中で用いる。
$par4 = "string 'bb'";    # シングルクオート自身をあらわすには、ダブルクオートの中で用いる。
$par5 = "string \"aa\"";  # ダブルクオートのなかで、ダブルクオートを表したいときは、\を用いる。
$par6 = 'string \'bb\'';  # シングルクオートの時も同じ。

$par7 = "$par1$par2";     # ダブルクオートの中では、変数は展開される。この場合、文字列 aabb が代入される。
$par8 = '$par1$par2';     # シングルクオートの中では、変数は展開されない。この場合、文字列 $par1$par2 が代入される。

$par9 = "10";             # 文字列 10 を代入。整数の10ではない。

$par9 = $par9 + 0;        # 文字列 10 を整数の 10 に型変換(?)したいときは、0を足す。たしか。
$par9 = $par9 . "";       # 整数 10 を文字列の 10 に型変換(?)したいときは、空文字列 "" を結合させる?

■ 変数の書き方

変数の書き方にはいろいろある。

# 以下、5つの書き方は、すべて同じ意味で、$par1 に文字列 aa を代入している。
$par1 = "aa";
${par1} = "aa";          
${"par1"} = "aa";        
${'par1'} = "aa";        
${"pa" . "r1"} = "aa";    # . は文字列結合演算子。

# さらに、以下のように書いても、$par1 に文字列 aa を代入している。
$str = "par1";
${"$str"} = "aa";
${$str} = "aa";
$$str = "aa";

# さらに、以下のように書いても、$par1 に文字列 aa を代入している。

${$tmp0="par0"; $tmp1="par1";} = "aa";
${&fun();} = "aa"; 

sub fun{
return "par1";
}

配列変数

■ 代入

配列変数では、複数のデータをいっぺんに扱うことができる。配列の添え字は0から始まる。配列のi番目の要素にアクセスするには、$配列名[i]とする。

@arr = ("aa", "bb", "cc");
# 配列変数 @arr に文字列を代入。
# すなわち、配列の要素0に文字列 aa 、要素1に文字列 bb 、要素2に文字列 cc を代入。
# これは、以下の文と同値。
$arr[0] = "aa";
$arr[1] = "bb";
$arr[2] = "cc";

配列変数には、整数、実数、文字列などの異なる型のものでも1つの配列に格納できる。そもそも型はあるんだろうか。

@arr = ("aa", 1000, 1.4142);
# $arr[0] に 文字列 aa 、$arr[1] に 整数 1000 、$arr[2] に 実数 1.4142 を代入。

■ 配列の要素数

配列変数をスカラー変数に代入すると、配列の要素数が代入される。また、$#配列名というスカラー変数は、配列の最後の要素の添え字の値、すなわち、配列の要素数から1引いた数を格納する。

#!/usr/bin/perl

@arr = ("aa", "bb", "cc");
$num1 = @arr;             # 配列の要素数 3 を代入。
print @arr, "\n";         # 配列の中身をすべて表示。
print $num1, "\n";        # $num1の値 3 を表示。


$num2 = $#arr;            # 配列の最後の添え字の値 2 を代入。
print $#arr, "\n";        # 配列の最後の添え字の値 2 表示。
print $num2, "\n";        # $num2の値 2 を表示。

exit;
実行結果
aabbcc
3
2
2

ちなみに、配列とリストの違い。

@arr = ("aa", "bb", "cc");
$val1 = @arr;               # 配列の要素数 3 を $val1 に代入。
$val2 = ("aa", "bb", "cc"); # リストの最後の要素 cc を $val2 に代入。

■ 配列のリセット

配列の要素をすべて空にする方法は、とりあえず以下の2通り。

@arr = ("aa", "bb", "cc");
@arr = ();               # 空のリストを代入し、配列リセット。

@arr = ("aa", "bb", "cc");
$#arr = -1;              # 配列の最後の添え字の値を -1 にして、配列リセット。

未定義値undefを代入しても、配列の要素数は-1にならない。undefって何者?

@arr = ("aa", "bb", "cc");
@arr = (undef, undef, undef);    # 未定義値 undef 代入。
print $#arr, "\n";               # 配列の最後の添え字の値を表示。2が表示される。
@arr = ();                       # 配列を空に。
print $#arr, "\n";               # 配列の最後の添え字の値を表示。-1が表示される。

■ 配列の参照

配列の要素すべてにアクセスする方法を示す。

#!/usr/bin/perl

@arr = ("v0", "v1", "v2");

for ($i = 0; $i <= $#arr; $i++) {
  print "$arr[$i] ";
}
print "\n";
for ($i = 0; $i < @arr; $i++) {
  print "$arr[$i] ";
}
print "\n";
foreach $arr_val (@arr) {
  print "$arr_val ";
}
print "\n";

exit;
実行結果
v0 v1 v2 
v0 v1 v2 
v0 v1 v2 

■ スライス

配列の要素の一部を抜き出したり、配列の要素を入れ替えるには、スライス[ ]を用いる。

#!/usr/bin/perl

@arr1 = ("v0", "v1", "v2", "v3", "v4");
@arr2 = @arr1[0,2,4];            # @arr1の0,2,4の要素を抜き出し、@arr2に代入。
@arr3 = @arr1[1,0,2,3,4];        # @arr1の0と1の要素を入れ替えたものを、@arr3に代入。
@arr4 = @arr1[0,0,1,1,0];        # @arr1の0と1の要素を抜き出し、@arr4に代入。
@arr5 = @arr1[0..3];             # @arr1の0から3の要素を抜き出し、@arr5に代入。
@arr6 = @arr1[0..2,1];           # @arr1の0から3の要素と1の要素を抜き出し、@arr6に代入。
@arr7 = @arr1[0..2, 1..3, 2..4]; # @arr1の0から3の要素と1の要素を抜き出し、@arr7に代入。

print "1: @arr1\n";
print "2: @arr2\n";
print "3: @arr3\n";
print "4: @arr4\n";
print "5: @arr5\n";
print "6: @arr6\n";
print "7: @arr7\n";

exit;
実行結果
1: v0 v1 v2 v3 v4
2: v0 v2 v4
3: v1 v0 v2 v3 v4
4: v0 v0 v1 v1 v0
5: v0 v1 v2 v3
6: v0 v1 v2 v1
7: v0 v1 v2 v1 v2 v3 v2 v3 v4

配列の要素の一部に代入するときにも、スライスが使える。

#!/usr/bin/perl

@arr1 = ("v0", "v1", "v2", "v3", "v4");
@arr2 = ("v0", "v1", "v2", "v3", "v4");
@arr2[1..3] = @arr1[0,2,4];      # @arr1の0,2,4の要素が、@arr2の1から3に代入。
@arr3[2..4,6] = @arr1;           # @arr1の0から3の要素が、@arr3の2,3,4,6に代入。

print "1: @arr1\n";
print "2: @arr2\n";
print "3: @arr3\n";

exit;
実行結果
1: v0 v1 v2 v3 v4
2: v0 v0 v2 v4 v4
3:   v0 v1 v2  v3

スライスはリストにも使える。

#!/usr/bin/perl

@arr1 = ("v0", "v1", "v2", "v3", "v4")[0,2,4];
print "@arr1\n";

exit;
実行結果
v0 v2 v4

[ ]の中は、変数でもリストでも、サブルーチンでも良い。

#!/usr/bin/perl

$n_0 = 0;
$n_1 = 1;

@arr1 = ("v0", "v1", "v2", "v3", "v4");
@arr2 = (1,2,3);
@arr3 = @arr1[$n_0 .. $#arr1];   # @arr1の要素すべてを@arr2に代入。
@arr3 = @arr1[@arr2];            # @arr1の1,2,3の要素を抜き出し、@arr3に代入。
@arr4 = @arr1[@arr2, @arr2];     # @arr1の1,2,3,1,2,3の要素を抜き出し、@arr4に代入。
@arr5 = @arr1[(1,1,2,2,3)[0,4]]; # @arr1の1,3の要素を抜き出し、@arr5に代入。
@arr6 = @arr1[@arr2[0,1]];       # @arr1の1,2の要素を抜き出し、@arr6に代入。
@arr7 = @arr1[@arr2[$n_0,$n_1]]; # 上と同じ。
@arr8 = @arr1[&fun1()];          # @arr1の0,2,4の要素を抜き出し、@arr8に代入。
sub fun1 {
  return 0,2,4;
}
@arr9 = @arr1[&fun2()];          # @arr1の1から3の要素を抜き出し、@arr9に代入。
sub fun2 {
  return 1..3;
}

print "1: @arr1\n";
print "2: @arr2\n";
print "3: @arr3\n";
print "4: @arr4\n";
print "5: @arr5\n";
print "6: @arr6\n";
print "7: @arr7\n";
print "8: @arr8\n";
print "9: @arr9\n";

exit;
実行結果
1: v0 v1 v2 v3 v4
2: 1 2 3
3: v1 v2 v3
4: v1 v2 v3 v1 v2 v3
5: v1 v3
6: v1 v2
7: v1 v2
8: v0 v2 v4
9: v1 v2 v3

ファイルの任意の行を読み込みたいときに、スライスが使える。

# ファイル名: datを読み込み、1,3,5行目を@arrに代入するには、以下のようにする。
open(IN,"dat");
@arr = (<IN>)[0,2,4];
close(IN);

■ 二次元配列

二次元配列も扱える。

#!/usr/bin/perl

# 二次元配列に値代入。2*2の正方行列っぽく。
@arr1 = (
	   [ "v00", "v01" ],
	   [ "v10", "v11" ]
    );
# 上記は、以下のように書いても同じ。
# $arr1[0][0] = "v00";
# $arr1[1][0] = "v10";
# $arr1[0][1] = "v01";
# $arr1[1][1] = "v11";

# 二次元配列に値代入。要素数が行によってばらばらでもOK。
@arr2 = (
	   [ "vv00", "vv01" ],
	   [ "vv10", "vv11", "vv12", "vv13" ],
	   [ "vv20", "vv21", "vv22" ]
    );

# m行n列の要素を参照するには、$配列名[m][n]とする。ただし、m, n∈{0, 1, 2, ...}

print "$arr1[0][0]\n";    # \nは改行を表す。
print "$arr1[1][0]\n";
print "$arr1[0][1]\n";
print "$arr1[2][2]\n";    # 未定義値(?)を参照。
print "$arr1[1][1]\n";

print "$arr2[0][0]\n";
print "$arr2[1][1]\n";
print "$arr2[1][3]\n";
print "$arr2[1][4]\n";    # 未定義値(?)を参照。
print "$arr2[2][2]\n";

exit;
実行結果
v00
v10
v01

v11
vv00
vv11
vv13

vv22

■ 二次元配列の要素数

二次元配列の要素数を求める。配列変数をスカラー変数に代入すると、配列の要素数が代入される。また、$#配列名という値は、配列の最後の要素の添え字の値、すなわち、配列数から1引いた数になる。

@arr = (
	   [ "vv00", "vv01" ],
	   [ "vv10", "vv11", "vv12", "vv13" ],
	   [ "vv20", "vv21", "vv22" ]
    );
$row = @arr;             # $rowに@arrの行数である 3 が代入される。
$col0 = @{$arr[0]};      # $col0 に@arrの0行目の要素数である 2 が代入される。
$col1 = @{$arr[1]};      # $col1 に@arrの1行目の要素数である 4 が代入される。
$col2 = @{$arr[2]};      # $col2 に@arrの2行目の要素数である 3 が代入される。

$row = $#arr;            # $rowに@arrの行数から1を引いた 2 が代入される。
$col0 = $#{$arr[0]};     # $col0 に@arrの0行目の要素数から1を引いた 1 が代入される。
$col1 = $#{$arr[1]};     # $col1 に@arrの1行目の要素数から1を引いた 3 が代入される。
$col2 = $#{$arr[2]};     # $col2 に@arrの2行目の要素数から1を引いた 2 が代入される。

■ 二次元配列の参照

二次元配列の要素すべてにアクセスする方法を三つ示す。

#!/usr/bin/perl

@arr = (
	   [ "v00", "v01" ],
	   [ "v10", "v11", "v12", "v13" ],
	   [ "v20", "v21", "v22" ]
    );

print "method 1\n";
for ($i = 0; $i <= $#arr; $i++) {
  for ($j = 0; $j <= $#{$arr[$i]}; $j++) {
    print "$arr[$i][$j] ";
  }
  print "\n";
}

print "method 2\n";
for ($i = 0; $i < @arr; $i++) {
  for ($j = 0; $j < @{$arr[$i]}; $j++) {
    print "$arr[$i][$j] ";
  }
  print "\n";
}

print "method 3\n";
foreach $arr_ref (@arr) {
  foreach $arr_val (@{$arr_ref}) {
    print "$arr_val ";
  }
  print "\n";
}

exit;
実行結果
method 1
v00 v01 
v10 v11 v12 v13 
v20 v21 v22 
method 3
v00 v01 
v10 v11 v12 v13 
v20 v21 v22 
method 2
v00 v01 
v10 v11 v12 v13 
v20 v21 v22 

参考文献・webページ


ページ制作履歴
2008/02/10 制作開始
2007/02/11 アップ