書評のようなもの ++ 雅なPerl入門
@koji_magi @krocoke 感想なんかも教えて欲しいですね。あんまりフィードバックがないので。冬コミも申し込んでるので、イラスト期待ですね!!
— kaz_hiramatsu (@kaz_hiramatsu) September 20, 2013
ということで、先日のYAPC::Asiaにて入手した雅なPerl入門という同人誌の
感想など記事にしてみようと思います。
ちなみに中身は健全なPerl学習用の本ですので、
その点をふまえた上で、興味がある方は先へお進みください。
表紙
まごうことなく同人誌ですね。
即売会という響きも久しく聞いていない身ですが
これはいいものです。
後から気づいたのですが、知人が表紙絵を書いておりました。
縁とは意外な所で繋がるものです。
目次
本編に入る前に、まずは目次をご覧あれ。
- 第1章 プロローグ
- 第2章 Perl を知ろう
- 2.1 Perl の特徴
- 2.2 Perl のスローガン
- 2.3 CPAN
- 2.4 コミュニティ
- 2.5 YAPC
- 第3章 Perl の開発環境を整えよう
- 3.1 Perl をインストールする
- 3.2 plenv のインストール
- 3.3 Perl のバージョンを切り替える
- 3.4 Hello, world
- 3.5 プログラムを実行しよう
- 3.6 Hello, world の解説
- 3.7 say 関数
- 3.8 コメント
- 第4章 スカラー
- 4.1 Perl の基本的なデータ型
- 4.2 浮動小数点数リテラル
- 4.3 整数リテラル
- 4.4 数値用の演算子
- 4.5 if 文と比較演算子
- 4.6 ブール値
- 4.7 unless 文
- 4.8 if、unless 修飾子
- 4.9 文字列
- 4.10 文字列リテラル
- 4.11 シングルクォート文字列
- 4.12 ダブルクォート文字列
- 4.13 文字列のエンコーディング
- 4.14 文字列演算子
- 4.15 文字列の比較演算子
- 4.16 演算子による数値と文字列の自動変換
- 4.17 論理演算子
- 4.18 論理演算子を使った初期化
- 4.19 //演算子
- 4.20 演算子の優先順位と結合性
- 第5章 配列とリスト
- 5.1 配列とリストとは
- 5.2 配列の変数展開
- 5.3 配列への代入
- 5.4 リストへの代入
- 5.5 qw ショートカット
- 5.6 配列に対する操作
- 5.7 for 文
- 5.8 push 関数
- 5.9 pop 関数
- 5.10 shift 関数
- 5.11 unshift 関数
- 5.12 sort 関数
- 5.13 reverse 関数
- 5.14 join 関数
- 5.15 map 関数
- 第6章 ハッシュ
- 6.1 ハッシュとは
- 6.2 ハッシュに対する操作
- 6.3 keys 関数
- 6.4 values 関数
- 6.5 each 関数
- 6.6 exists 関数
- 6.7 delete 関数
- 第7章 サブルーチン
- 7.1 サブルーチンの定義と呼び出し
- 7.2 サブルーチンの引数
- 7.3 引数の渡し方
- 7.4 サブルーチンの戻り値
- 7.5 サブルーチンとパッケージ
- 第8章 コンテキスト
- 8.1 演算子とコンテキスト
- 8.2 スカラーコンテキスト
- 8.3 リストコンテキスト
- 第9章 正規表現
- 9.1 正規表現とは
- 9.2 メタ文字と通常文字
- 9.3 正規表現の文法
- 9.4 文字そのものを指定するパターン
- 9.5 .(ドット)
- 9.6 []
- 9.7 \d と \D
- 9.8 \w と \W
- 9.9 量を指定するパターン
- 9.10 a+
- 9.11 a*
- 9.12 a?
- 9.13 a{m,n}
- 9.14 よくばりとなまけもの
- 9.15 位置に関するパターン
- 9.16 ^と$
- 9.17 \A と \Z
- 9.18 \z
- 9.19 特殊な指定に関するパターン
- 9.20 a|b
- 9.21 (a)
- 9.22 a(?:a)
- 9.23 a(?=b)
- 9.24 a(?!b)
- 9.25 a(?<=b)
- 9.26 s/a/b/
- 9.27 split 関数
- 第10章 リファレンス
- 10.1 リファレンスとは
- 10.2 リファレンスの生成
- 10.3 スカラー変数のリファレンス
- 10.4 配列変数のリファレンス
- 10.5 モジュールの Data::Dumper の使用について
- 10.6 ハッシュ変数のリファレンス
- 10.7 矢印記法
- 10.8 無名のメモリ領域へのリファレンス
- 10.9 コードリファレンス
- 第11章 CPAN モジュール
- 11.1 CPAN モジュールとは
- 11.2 cpanm のインストール
- 11.3 cpanm を使ってモジュールをインストールする
- 第12章 オブジェクト指向
- 12.1 オブジェクト指向とは
- 12.2 1. パッケージを作成する
- 12.3 2. new メソッドでリファレンスとパッケージ名を bless する
- 12.4 3. パッケージにメソッドを書く
- 12.5 4. モジュールをインストールする
- 12.6 5. new メソッドを呼んでオブジェクトを作成する
- 12.7 6. オブジェクトに対してメソッドを呼び出す
- 12.8 継承
- 12.9 メソッドのオーバーライド
- 12.10 メソッドのインポートとエクスポート
- 12.11 use とは
- 12.12 名前と変数のスコープについて
- 12.13 カスタムな import メソッド
- 12.14 File::Slurp
- 12.15 Encode
- 12.16 Path::Tiny
- おわりに
これを見るだけでも、基本を網羅した構成であることは
十分に伝わると思います。
自分がPerlを学んだ分厚い参考書と比べても
ページ数の差はあれど、中身では負けてない、という感想でした。
このクオリティで同人誌とは…恐るべし。
技術書としての感想
まず技術書としての話ですが、
対象は初学者から言語の基本をある程度おさえた中級者向け、くらいの内容になっていました。
なので、Perlに興味がある別言語の経験者の方や、
Perlはある程度触れるかな、くらいの人ならほぼつまずかないで読める内容だと思います。
参考までに、自分はWeb系の実務経験が三年半ほど、恐らく中級者に片足かけたくらいで
大体の内容は分かりつつ、知らないことも幾つかあった、という感じでした。
9章の正規表現で出てきた「よくばりとなまけもの」の話は
初めて知る内容で、とても勉強になりました。
ノートPCを置いといて、つまづいた所が出たらperldocを叩いたり、サンプルコードを打ち込む感じで
読み進めていきました。
内容は幅広く基礎を扱っているので、どの章も読み応えはありましたが
特に、環境構築にplenvを使っていた点と、Encodeを取り上げて文字コードの変換に触れている点が
好印象でした。
個人的には5、6章の組み込み関数はよく使うので
もう少し実例的なサンプルがあってもいいかな、という気もしました。
そういえばmap関数はあったのにgrep関数が無かったですね…もしかしてgrepってマイナーなのかな。
あとは、11.3でモジュールを入れる例として「cpanm Moose」していたけど
もう少しさくっと入るモジュールの方がいいかなと思いました。
依存が多くて時間かかりますし、何かしらテストこけそうな気が…。
(あえて茨の道を味わってみるのもアリと言えばアリですが!)
蛇足かと思いましたが、誤植や間違いとおぼしき箇所については
出来る限りメモしておいたので、本記事の最後にまとめて記しておきます。
誤植まとめに誤りなどありましたら、コメント頂けると有り難いです。
ラノベ読みとしての感想
さて、ここからが本気の出しどころですね。
著者の@kaz_hiramatsuご本人も「ラノベを読む感覚で」と後書きされていますが
この本は物語仕立てになっています。
Perlを学びたい雅という女の子がクロウというPerlハッカーに教えを乞う、という流れですが
この二人の対話形式、凄く良いです。
クロウの人物設定は、某hatenaさんあたりにこんな学生さん居そうだなーというリアルさがあるし
雅は雅で「そんな奴いねえYO!」という部分と「いや、でもこういうことする奴居そうだな…」という
居なそうで居そう、という良い塩梅を突いたキャラになっていて
自分は好きな感じでした。
あと、最も興味深かったのが、雅の的確なコメントです。
この妙に的確コメントが、雅のキャラ設定を膨らませる燃料になっていたように感じました。
プロローグで人物の説明があったクロウに対し、雅はキャラ設定についてはっきりと書かれている場面はありません。
しかし、例えば2.2のやりとりを引用してみると
クロウ: (省略)... Perl のプログラムは、同じ事をやる場合でもいろんな書き方が出来るんだ。
雅: いろんな書き方ができると、プログラムが読みにくくなる気がしますけど。
このコメント、何やら「ん?」と思わされます。
「読みにくく」ということは、「プログラムは読むもの」という認識があることになります。
つまり、雅はある程度、プログラムを読む習慣があると推測できます。
また、「見る」ではなく「読む」という表現からも、プログラムに普段から触れている空気を感じ取る事ができます。
一方、4.3では整数リテラルの説明に対して、このようなコメントを返しています。
雅: 数値もほとんど数学と同じですね。意外とプログラミングって簡単な気がして来ました。
さもプログラム初心者であるかのようなコメントです。
雅はプロローグでPerlを知らないと言っているので、一見すると自然に見えますが
前述のコメントがあるので、まるで初心者を「装っている」ように見えてきます。
この後も、雅のコメントが的確すぎて
進めば進むほど「もしや正体を隠しているのでは?」という疑問が強くなってくるという
不思議なモチベーションに押されつつ、サクサクと読み進める事ができました。
うっかりエピローグが用意されていて「実は私はMiyabiではなくMiyagawaだったのさ!」「な、なんだっtt」
という超展開を妄想したりもしましたが、そんなことには全然なっていなかったので
残念ほっと一安心でした。
まとめ
Perlを学ぶ本としても良い本ですし、ラノベ好きとしても楽しめる一冊でした。
Perl好きなら持っておいて、間違いは無いかと。
もし次回があれば中級者向けの本を、と後書きにありましたので
次の本も手にする機会があれば、是非よんでみたいと思います。
誤植、間違い等まとめ
P13. 下方のサンプルコード4行目
誤:小数点以下3桁
正:小数点以下6桁
P16. 7行目
誤:$x、$y、$x
正:$x、$y、$z
P19. 表4.1、$x >= $y の意味
誤:$x より$y が大きいか等しい
正:$x は$y より大きいか等しい
P22. 4.8の三つ目の会話
誤:話者が雅
正:話者がクロウ
P31. 表4.3、$x ge $y の意味
誤:$x はより$y は大きいか等しい
正:$x は $y より大きいか等しい
P31. 表4.3、$x le $y の意味
誤:$x より$y は小さいか等しい
正:$x は$y より小さいか等しい
P32. 一つ目のサンプルコードのコメント
誤:"10" + "20"
正:"10" . "20"
P50. 下段のサンプルコード、一行目
誤://emlist{
正:この行が不要
P77. 9.14の最後のクロウの台詞
誤:マッチする文字列の中で最も短いもの
正:マッチする文字列の中で最初にマッチしたもの
実際にコードを叩いて確かめてみると、説明とは違って長い方にマッチします
perldoc perlreでは、以下のように説明されています
By default, a quantified subpattern is "greedy", that is, it will match
as many times as possible (given a particular starting location) while
still allowing the rest of the pattern to match. If you want it to
match the minimum number of times possible, follow the quantifier with
a "?". Note that the meanings don't change, just the "greediness":
*? Match 0 or more times, not greedily
+? Match 1 or more times, not greedily
?? Match 0 or 1 time, not greedily
{n}? Match exactly n times, not greedily (redundant)
{n,}? Match at least n times, not greedily
{n,m}? Match at least n but not more than m times, not greedily
P81. 表9.5、メタ文字の(?:b)
誤:(?:b)
正:(?:a)
「意味」の項目が「パターンaのグループ化」になっていたので、表の流れから考えて、
「意味」ではなく「メタ文字」の項目を直す形にしています
P84. 9.25項目全体
ここは恐らく(?<=)の説明として、9.25の中身自体が適切ではないです
perldoc perlreから、(?<=)の説明を一部抜粋します
"(?<=pattern)" "\K"
A zero-width positive look-behind assertion. For example,
"/(?<=\t)\w+/" matches a word that follows a tab, without
including the tab in $&. Works only for fixed-width look-
behind.
ざっくり訳すと、「タブ文字列(\t)に文字列が一文字以上繋がってる場合にマッチするけど、
$&(マッチした文字列が入る変数)にタブは含まないよ」となります
こんな感じのワンライナーを書くと、実際に動きが確認出来ます
$ perl -E 'if ("\taaa" =~ /(?<=\t)\w+/) { say $& }'
aaa
P115. サンプルコード、new関数の下から二行目のコメント
誤:空のハッシュリファレンスを用意
正:空じゃない