--- title: '『新版Perl言語プログラミングレッスン入門編』第6章: 繰り返し' author: kazu634 date: 2008-02-06 url: /2008/02/06/_839/ wordtwit_post_info: - 'O:8:"stdClass":13:{s:6:"manual";b:0;s:11:"tweet_times";i:1;s:5:"delay";i:0;s:7:"enabled";i:1;s:10:"separation";s:2:"60";s:7:"version";s:3:"3.7";s:14:"tweet_template";b:0;s:6:"status";i:2;s:6:"result";a:0:{}s:13:"tweet_counter";i:2;s:13:"tweet_log_ids";a:1:{i:0;i:3691;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}' categories: - Perl - Programming ---
繰り返しについて勉強するよー
これまで何度も出てきた構文。変数の中にリストの値を順番に格納する構文だよ。基本構造は
foreach my 変数 (リスト) { 処理 }
というようになる。「my 変数」は省略可能で、処理の中で「$_」と表記できる。例はこんな感じ:
use strict; use warnings; my @name = ('Musashi', 'Aiko', 'Nanbu'); foreach (@name) { print "$_\n"; }
リストの値でソートさせて表示させたいときにはこのようにする。
use strict; use warnings; my @name = ('Musashi', 'Aiko', 'Nanbu'); foreach (sort(@name)) { print "$_\n"; }
逆順にソートするときは「reverse(sort(@name))」とすればいい。reverseは「リストの内容を単純に逆にするだけ」ということに注意。だから「reverse(@name)」は
という結果になるよ!当たり前だけど、foreachを二重(orそれ以上)にすることもできる。例としてはこんなのが載っていた:
use strict; use warnings; my @data = ( "Musashi, 70, 83, 41", "Aiko, 90, 70, 50", "Nanbu,100, 30, 20", ); foreach (@data) { my ($name, @score) = split(/,/, $_); my $sum = ; foreach (@score) { $sum += $_; } print "$name: $sum\n"; }
自分としては「my ($name, @score) = split(/,/, $_);」がファジーすぎると感じる。説明によれば、
split(/,/, $line)は、$lineの文字列をコンマで区切り、そのそれぞれの要素をまとめたリストを作ります。例えば、$lineの値が
'Hiroshi Yuki, 70, 83, 41'
だとすると、split(/,/, $line)の値は、
('Hiroshi Yuki', '70', '83', '41')というリストになります。代入する先の左辺は、($name, @score)というリストになっているので、
my $name = 'Hiroshi Yuki'; my @score = ('70', '83', '41');と同じことになります。
「同じことになる」で済ませられているけど、なんかかなりファジーな気がするんですが。。。でも、直感的と言えば直感的かもしれない。要は「最初のヤツだけ$nameに格納、後は@scoreにまとめちゃって」ということなんだろう。
foreach構文の使い道は他にもあって、「ファイルの各行を読み込む」時にも使うよ。例はこんな感じになる。
use strict; use warnings; open (FILE, 'file.txt') or die "$!"; foreach (<FILE>) { print $_; } close (FILE);
説明にはこんな事書いてあったよ!
「リスト」のところには
と書いてあります。Perlではリストを書くべきところに と書くと、FILEというファイルハンドルからすべての行をメモリ上に読み込み、その各行を要素とするリストを作成します。これはPerlの約束です。
他にも「ディレクトリ内部の各ファイルの繰り返し」にも使えるよ!
use strict; use warnings; opendir (DIR, '.') or die "$!"; foreach (readdir(DIR)) { print "$_\n"; } closedir (DIR);
この前の章でもやったけど、「keysを使うとハッシュを表示できる」よ♪
use strict; use warnings; my %hash = ( 'Kazu' => 10, 'Yukari' => 20, 'Aiko' => 30, 'Nanbu' => 40, ); foreach (keys(%hash)) { print "$_: $hash{$_}\n"; }
「keys(%hash)」で「(‘Kazu’, ‘Yukari’, ‘Aiko’, ‘Nanbu’)」というリストが得られるよ!なにげに「”$_: $hash{$_}\n”;」を「”$_: %hash{$_}\n”」としてしまい、ややはまる。抜けているなー。
whileの処理はこんな感じになっている:
while (条件式) {
繰り返す処理
}
条件式が満たされている間中はずっと繰り返し処理を行う。例はこんな感じ。
use strict; use warnings; open (FILE, 'temp.txt') or die "$!" while (my $line = <FILE>) { print $line; } close(FILE);
これを別な書き方にもできる。
use strict; use warnings; open (FILE, 'temp.txt') or die "$!" while (<FILE>) { print $_; } close(FILE);
この「$_」の使い方も少し不思議だけど、説明によると:
whileの中で
を使うと、読んだ行の内容がデフォルト変数$_に代入されます。
というわけで、お約束らしい。