「初めてのPerl」 6章 (入出力の基本)

mixiの1979(昭和54)年会のトピックで知ったのですが、「俺たち、サザエさんのアナゴさんとタメだ。」そうです。素でショックです…。という話はさておき、少し間が空きましたが、まだちゃんとPerlを勉強しているbonlifeです。6章では入出力の基本について扱っています。演算子を使って標準入力を読み込む方法や<>(ダイヤモンド演算子!)を使って起動引数を読み込む方法が紹介されています。後半部分ではprintfを使ったフォーマット付き出力(出力の整形)についても簡単に触れられています。ということで、6章の演習問題のnot模範解答です。
ex6-1.pl

  • catのような振舞いをするプログラムを書く
  • 出力を逆順に行う (複数の引数を指定した場合、最後の引数の最後の行から表示)
#! perl -w
use strict;
print reverse <>;

出力結果は以下の通り。

ex6-1.pl test01.txt test02.txt test03.txt
line 5 of test03.txt
line 4 of test03.txt
line 3 of test03.txt
line 2 of test03.txt
line 1 of test03.txt
line 5 of test02.txt
line 4 of test02.txt
line 3 of test02.txt
line 2 of test02.txt
line 1 of test02.txt
line 5 of test01.txt
line 4 of test01.txt
line 3 of test01.txt
line 2 of test01.txt
line 1 of test01.txt

正解を見て気づいたことは特になし。同じ。
ex6-2.pl

  • 文字列のリストを1行に1個ずつ読み込んで、20文字幅のカラムに右寄せ表示
  • 出力を確認するために目盛りも出力
#! perl -w
use strict;
my ($count, @words, $word);
print "Please input some words : \n";
chomp(@words = <STDIN>);
$count = 0;
while ($count < 6 ) {
	foreach (1..10) {
		if ( $_ != 10 ) {
			print $_ ;
		} else {
			print 0;
		}
	}
	$count += 1;
}
print "\n";
foreach $word (@words) {
	printf "%20s\n", $word ;
}

出力結果は以下の通り。(^Zまでは入力)

ex6-2.pl
Please input some words :
hello
good-bye
^Z
123456789012345678901234567890123456789012345678901234567890
               hello
            good-bye

正解を見て気付いたことは以下の通り。

  • 目盛りの出力方法が冗長 (解答例では x を使って1234567890を繰り返し)
    ベタに1234...と記述するのを避けようと思ったのが裏目に出てしまいました
  • foreachでの出力では、変数名を宣言せず、デフォルトの $_ を使う

ex6-3.pl

  • 2のプログラムを改造して、ユーザがカラム幅を指定できるようにする
    例えば30とhelloとgood-byeを入力すると、30文字幅のカラムに右寄せで表示
  • 長い幅を指定された場合は、それに合わせて目盛りも伸ばす
#! perl -w
use strict;
my ($count, @words, $word, $col, $ruler_size);
print "Firstly, please input column number.\nAfter that, pls input some words : \n";
chomp(@words = <STDIN>);
$col = shift(@words);
$ruler_size = $col / 10;
if ( $ruler_size < 6 ) {
	$ruler_size = 6;
} 
$count = 0;
while ( $count < $ruler_size ) {
	foreach (1..10) {
		if ( $_ != 10 ) {
			print $_ ;
		} else {
			print 0;
		}
	}
	$count += 1;
}
print "\n";
foreach $word (@words) {
	printf "%${col}s\n", $word ;
}

出力結果は以下の通り。(^Zまでは入力)

ex6-3.pl
Firstly, please input column number.
After that, pls input some words :
18
hello
good-bye
^Z
123456789012345678901234567890123456789012345678901234567890
             hello
          good-bye
ex6-3.pl
Firstly, please input column number.
After that, pls input some words :
75
hello
good-bye
^Z
12345678901234567890123456789012345678901234567890123456789012345678901234567890
                                                                      hello
                                                                   good-bye

正解を見て気付いたことは以下の通り。

  • カラムの指定と単語の入力は分けて行わせた方が分かりやすい
  • 解答例では、目盛りの伸ばし方が絶妙
    "1234567890"を(指定文字幅+9)/10回(切捨て)繰り返す

3問目で数学的な発想が欠如していることを思い知らされました。むむぅ。まぁ、とりあえず動くソースが書けたのでオーケーということにしておきます。ダイヤモンド演算子を上手いこと使えば現在シェルでやってるようなことがだいぶ出来る気がします。後は11章のファイルハンドルについてもきっちり学んでおく必要がありそうですね。引き続き細々とPerlを勉強していきます!