Perl入学式 #7補講に参加した
課題に対する私の回答などは前回のエントリーにあるので興味のある人はどうぞ。このエントリーは主に感想などを。
全体の感想
毎度のことだけど、詰め込みすぎ。今回は、map / grep の話と正規表現の話になってましたが、3時間の枠でこれだけの話をするのは無理がある。
いずれの話題も初学者には非常にとっつき難いので、もっと沢山演習を用意して色んなパターンを参加者が試すことができるようにした方がよいと感じた。
個別の話題
grep / map
多用するとコードが厨二っぽくなるアレ。講義の中では自前で grep のようなブロックを取る関数を定義するのは無理、というような話だったけど、List::Util::reduce とかあるので、プロトタイプ宣言すれば定義できるような気がする。
でもローカル変数の使い方がやっぱりよくわからん、自ら進んで定義しようとは思わんな、無名関数を引数に渡してしまった方が簡単だしわかりやすい。唯一、
map { .. } grep { .. } @list
みたいにチェーンしたい場合には有効なのかもしれん。でも ruby の書き方の方が好き。
list.select { |x| ... }.map { |x| ... }
慣れの問題か?
正規表現
話しだすときりがない、講義中にツイートしたように最初は「.* で任意の文字列にマッチする」程度でけっこう戦える。
講義中では正規表現のサンプルのために
下記の場合に出力しない
文字列がjohn, Johnを含む.
文字列の先頭にbetty, Bettyを含む.
文字列の最後にgreat, Greatを含む.
文字列がtomというアルファベットを含む(大文字・小文字問わず).
て感じの条件を一つの正規表現で頑張っていましたが、普通は個別に対応すればいいと思う
sub contain_john { return $_[0] =~ /john|John/; } sub start_with_betty { return $_[0] =~ /^(betty|Betty)/; } sub end_with_great { return $_[0] =~ /(great|Great)$/; } sub contain_tom { return $_[0] =~ /tom/i; } sub allow_print { my $target = shift; return 0 if contain_john($target); return 0 if start_with_betty($target); return 0 if end_with_great($target); return 0 if contain_tom($target); return 1; } while (my $line = <STDIN>) { print $line if allow_print($line); }
みたいに。あるいは switch を使うとか
use feature qw/switch/; sub allow_print { given($_[0]) { when (/john|John/) { 0 } when (/^(betty|Betty)/) { 0 } when (/(great|Great)$/) { 0 } when (/tom/i) { 0 } default { 1 } } } while (my $line = <STDIN>) { print $line if allow_print($line); }
演算子 =~ の動作が(スカラコンテキストとリストコンテキストで?)非常にわかり難かったので、ほんとうはもっと突っこんで聞いておきたかった。時間切れ。
その他
発表資料で利用されているプレゼンツールがちょっと不便。先頭ページからカーソルキーで順番にしかアクセスできない線形リスト方式なので、後で「配列の参照についてどっかで説明されていたはず」と思って探そうとしても、順番にページをめくっていくしかない。そしてページめくりのエフェクトがすげー邪魔。