続・初めてのPerl 第8章 「ファイルハンドルへのリファレンス」

練習問題の回答をメモ。

ex08-1
#!/usr/bin/perl
use strict;
use warnings;
use IO::Tee;

my $choice;
while (1) {
  print "1: File, 2: Scalar, 3: Both, q: quit\n";
  print "Which of above do you want your output to go?: ";
  chomp($choice = <STDIN>);
  last if $choice =~ /^\s*[123]\s*$/;
  exit 0 if $choice =~ /^\s*q\s*$/i;
  print "\nPlease choice between 1-3!\n"
}

my $fh;
my $scalar_output; # スカラー出力の場合に使う
my $file_name = 'hoge.out';
if ($choice eq "1") {
  open $fh, '>', $file_name or die "Could not open $file_name: $!"; # p.98
} elsif ($choice eq "2") {
  open $fh, '>', \$scalar_output or die "Could not open scalar: $!";
} else {
  open my $fh_tmp1, '>', $file_name or die "Could not open $file_name: $!"; # p.98
  open my $fh_tmp2, '>', \$scalar_output or die "Could not open scalar: $!";
  $fh = IO::Tee->new($fh_tmp1, $fh_tmp2);
}

my $dow = (localtime)[6];
my $day = localtime;
my @day_of_week = qw(Sun Mon Tue Wed Thu Fri Sat);

print $fh "date: $day $day_of_week[$dow]\n";

print "$scalar_output\n" if $choice =~ /^\s*[23]\s*$/;

$0(プログラム名) がファイルの名前として利用できたね。
ヒアドキュメントを利用できたね。
解答で使われていた $$ はプロセスID が格納されているよ。

ex08-2
#!/usr/bin/perl
use strict;
use warnings;
use IO::File;

@ARGV = "log_file.txt";
my %file;
while (<>) {
  my $line = $_;
  unless ($line =~ /^(\S+):/) {
    warn "skipping the line missing name: $line";
    next;
  }
#  my $name = (split /:/, $line)[0];
  my $name = lc $1;
  my $fh = IO::File->new(">> $name.info") or warn "Could not open $name: $!\n";
  print $fh $line;
}

この問題のヒントで、「名前をキーとし、出力ファイルに対応するIO::Fileオブジェクトを値とするハッシュを使いましょう。」とあるけど、ファイルを上書きモードで開けばハッシュを使うまでも無い気がする。いや、だけどよく考えてみると、毎回ファイルを開いている分だけ処理が重くなるのかな…。

ex08-3
#!/usr/bin/perl
use strict;
use warnings;
use IO::Dir;

foreach (@ARGV) {
  my $dir_fh = IO::Dir->new($_) or die "could not open $_: $!\n";
  print "$_ has files below:\n";
  while (defined(my $file = $dir_fh->read)) {
    print "$file\n";
  }
  print "\n";
}

解答を見たら、@ARGV をチェックして、ディレクトリ名でないものを除外していた。確かにこの処理は必要だな。

反省点

練習問題の字面だけを読まないで、意味を察して取り組もう。ほとんど意味の無いプログラムになっちゃうかもよ。