初めてのPerl 第16章
練習問題の回答をメモ。
ex16-1
#!/usr/bin/perl use strict; my $pod_path = `perldoc -l perlfunc`; open POD, $pod_path or die "Cannot open $pod_path: $!"; # 上の2行は以下の1行で置き換えられる。while(<POD>) を while(<>) に変える必要あり。 # @ARGV = `perldoc -l perlfunc`; my %DB; dbmopen(%DB, "pod_db", 0644) or die "Cannot open pod_db: $!"; %DB = (); while (<POD>) { if (/^=item\s+([a-zA-Z_]\w*)/) { $DB{$1} = $DB{$1} || $.; } } # DBM の内容を表示して確かめてみる while (my($func, $line_num) = each(%DB)) { print "<<$func>> first appeared on line <<$line_num>>\n"; }
ex16-2
#!/usr/bin/perl use strict; dbmopen(my %DB, "pod_db", undef) or die "Cannot open pod_db: $!"; my $func_name = $ARGV[0]; my $line_num = $DB{$func_name} || "Not Found"; print "<<$func_name>>: <<$line_num>>\n";
あれー、なんか警告っぽいのが出る…。
% perl -w ex16-2.pl hoge Use of uninitialized value in dbmopen at ex16-2.pl line 4. <<hoge>>: <<Not Found>>
dbmopen の第3引数に undef を指定すると、この警告が出るみたいなんだけど、何でだろう?0644 とかを指定すると出ないんだけどな。ex16-3 でも同じ警告が出る。
ex16-3
#!/usr/bin/perl use strict; dbmopen(my %DB, "pod_db", undef) or die "Cannot open pod_db: $!"; my $func_name = $ARGV[0]; if (my $line_num = $DB{$func_name}) { my $pod_path = `perldoc -l perlfunc`; exec "less +$line_num $pod_path" or die "less couldn't run: $!"; } else { print "Not found: $func_name\n"; }
反省点(と感想)
if文の代わりに、OR演算子|| をうまく使おう。
DBMハッシュをうまく利用すればデータの扱いが楽になるかも。