Perlベストプラクティス - その1
- 作者: Damian Conway,クイープ
- 出版社/メーカー: オライリー・ジャパン
- 発売日: 2006/08/24
- メディア: 大型本
- 購入: 10人 クリック: 140回
- この商品を含むブログ (151件) を見る
第5章:変数
5.8 $_の変更に注意
$_は言うに及ばずだが、myにも注意。実はエイリアス。
my @list = (1..5); for my $i (@list) { $i = 1; } printf("%s\n", join q{,}, @list); #1,1,1,1,1
第6章:制御構造
リストの生成
forではなくmapを使う
- 可読性が高くなる
# OK @double_vals = map { $_ * 2 } (1..5); # NG @double_vals = (); for my $val (1..5) { push @double_vals, $val * 2; }
リストの検索
forではなく、grepやfirstを使う
- コードの可読性が高まる
- 実行速度が速い
use Benchmark; my @list = (1..20); # NG sub impl_by_for { my @multiple_of_3; for my $i (@list) { push @multiple_of_3, $i if ($i % 3 ==0); } return @multiple_of_3; } # OK sub impl_by_grep { return grep { $_ % 3 == 0 } @list; } timethese(100_000, +{ 'impl_by_grep' => 'impl_by_grep()', 'impl_by_for' => 'impl_by_for()', });
Benchmark: timing 100000 iterations of impl_by_for, impl_by_grep...impl_by_for: 3 wallclock secs ( 2.16 usr + 0.01 sys = 2.17 CPU) @ 46082.95/s (n=100000)impl_by_grep: 2 wallclock secs ( 1.55 usr + 0.01 sys = 1.56 CPU) @ 64102.56/s (n=100000)
どちらがよいか、一目瞭然。
細かいところちゃんと意識してやっていきたいなぁ。
リスト変換
mapではなく、forを使う
- mapは一時的に配列のためのメモリを新たに割当てる
- 既存の配列が大きいとその分メモリを食うので、変換であればforが望ましい
第8章:組み込み関数
reverse
- リストコンテキストではリストを反転
print reverse (0..9), "\n";
- スカラーコンテキストでは文字を反転
print scalar(reverse 'abcdefg'), "\n";
テキストデータの分割
- 固定幅のフィールドの取得にはunpackを使う
- 可変幅で、シンプルなフィールドの取得にはsplitを使う
- 可変幅で、複雑なフィールドの取得にはText::CSV_XS(Text::CSV::Simple)を使う
1, 2は普通の話。実際にText::CSV_XSを使ってみる。データはidと名前だが、ダブルクォートがあったり、カンマの後にスペースがあったりとちょっと複雑。
11111,"kotaroito" 22222,kotaroito 33333, kotaroito
スクリプトはこちら。
use Text::CSV::Simple; my $csv_format = Text::CSV::Simple->new(+{ sep_char => q{,}, quote_char => q{"}, allow_whitespace => 1,}); $csv_format->field_map( qw( id name ) ); my @names; open my $fh, '<', 'test.csv'; for my $row_ref ($csv_format->read_file($fh)) { push @names, $row_ref->{name}; } close $fh; printf("%s\n", join qq{\n}, @names);
kotaro@mac:~$ perl test.pl
kotaroito
kotaroito
kotaroito
sep_charでフィールドを分割する文字を変えられるので、csvだけではなくtsvも可能。