[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)。