読者です 読者をやめる 読者になる 読者になる

[perl] はじめての Perl 第17章

練習問題の回答をメモ。

ex17-1
#!/usr/bin/perl
use strict;

my $filename = "sample_text";
open FILE, $filename
    or die "cannot open '$filename': $!";
my @lines = <FILE>;

while (1) {
  print "Enter a search pattern: ";
  chomp(my $pattern = <STDIN>);
  last if $pattern =~ /^$/;
  eval {
    my @matching_lines =  grep {/$pattern/} @lines;
    my $match_num = @matching_lines;
    print "$match_num lines matched:\n", @matching_lines;
  };
  if ($@) {
    print "invalid pattern: $@\n";
  }
  print "\n";
}

eval の戻り値をうまく使えば、例外を起こす可能性のある処理だけを eval の中に入れられたね。例えば、こんな感じ。

#!/usr/bin/perl
use strict;

my $filename = "sample_text";
open FILE, $filename
    or die "cannot open '$filename': $!";
my @lines = <FILE>;

while (1) {
  print "Enter a search pattern: ";
  chomp(my $pattern = <STDIN>);
  last if $pattern =~ /^$/;
  my @matching_lines = eval {
    grep {/$pattern/} @lines;
  };
  if ($@) {
    print "invalid pattern: $@\n";
  } else {
    my $match_num = @matching_lines;
    print "$match_num lines matched:\n", @matching_lines;
  }
  print "\n";
}

p.339 の解答ではファイルの各行末の改行文字を chomp演算子で取り除いてるけど、ユーザの入力したパターンだけ chomp すれば十分な気がするな。

反省点

eval の戻り値を効果的に使って、エラーが起こる可能性のあるスコープの範囲を明確にしよう。eval ブロックは本物のブロックだから、レキシカル変数(my変数)に対して新しいスコープを提供するよ(p.284)。

通読してみての感想

自分にとっては最高の入門書だった。この本の対象読者が途中で挫折しないような気遣いが随所に感じられて、Perlコースの教材として使われていたというのも納得できる。続・初めてのPerlも読んでみようと思う。