本書への質問、本書に載せきれなかったテクニック、セミナーなどの情報(予定)などを載せていきます。※正誤表の情報はこちらをご覧ください。7:正誤表(2)第3章練習問題2についてsironekotoroさんという方が、拙著『かんたんPerl』(以降本書と呼びます)をご購入の上、学習日記を公開してくださっています。ありがとうございます。その中の記事で、第3章の練習問題2が間違っているのではないだろうか。それも問題文に誤りがあるのではないか、というご指摘がありました。内容を確認したところ、たしかに本が間違っていたので、sironekotoroさんにご連絡し、ブログの紹介をご快諾いただきましたので、ここにご紹介すると共に、本書の内容を訂正してお詫びします。訂正とお詫び問題の問題はp.94のQ2です。問題文は以下のようです。Q2次のプログラムの穴埋めをして、月の英語名から数字を返すプログラムを作ってください。"英語で$monthは$num月のことです。";結果は以下のようになります。monthName.pl英語でMarchは3月のことです。この問題文の変数初期化を、以下のように訂正します。12"」の12と"の間に空白を入れるのが正解です。これで問題なく進めていただけると思います。申し訳ありませんでした。解説さて、以降は自分の間違いについて偉そうに解説を加えます。上のプログラム、穴埋め後の模範解答は以下のようになっていました。$monthの次に出てくる空白のオフセットを探す。次に出てくる空白のオフセットを探す。"英語で$monthは$num月のことです。";プログラム内にリテラルで「March」と月数を調べたい月の英語名を埋め込んでいるのですが、Marchについては確かに正しく動きます。./monthName.pl英語でMarchは3月のことです。ところが、これを「December」を調べるようにするとうまくいきません。$monthの次に出てくる空白のオフセットを探す。次に出てくる空白のオフセットを探す。"英語で$monthは$num月のことです。./monthName2.pl英語でDecemberは月のことです。[sample]$ダメですね。April..."のように空白を挟んで続いているので、まず月の英語名の次の空白を探して変数$num_sに記憶し、さらにその次の空白を$num_eに記憶する。その間の文字列を取得すれば、それが求める月の数字である、という前提に依って立っています。12"という風に、数字の後ろに空白がなく終わってしまいました。よって、$num_eはindex関数によって-1を返すので、月数の長さ$lenはマイナスの値になります。substr関数の第3引数(取得する文字列の長さ)としてマイナスの数を与えた場合、空文字列が返り、結果は「Decemberは月のことです」などという、ちょっと詩的な間違いになってしまいました。12"の末尾に空白を足してやれば済みます。$monthの次に出てくる空白のオフセットを探す。次に出てくる空白のオフセットを探す。"英語で$monthは$num月のことです。./monthName3.pl英語でDecemberは12月のことです。[sample]$現状のままなんとか解けないか?さて、上の問題は、問題文に穴埋めが必要なプログラムがあったのだが、その穴埋め以外の部分に問題文時点であらかじめ間違いがあったために、模範解答の穴埋めを埋めたプログラムがうまく動かないという問題でした。問題文に間違いがある状態で、なんとか無理矢理動くプログラムを作れないでしょうか。なんと、sironekotoroさんは天才的にも、この解決に成功してしまいました。いうことで、それをここでも紹介しようと思います。余談ですが、『かんたんPerl』を執筆するに当たって、各章の末尾に練習問題を付けることは、編集者の方の要望で決まりました。学校の教科書として使うときに、練習問題があった方が便利だということです。ぼくは賛同して、いろいろ練習問題を作ったのですが、非常に苦しみました。最初の方の問題を作るのに苦しみました。第1章では第1章までの、第2章では第2章までのプログラミングの知識しか使えないのです。よって、わずかなプログラムの機能で、しかもある程度面白い問題を作らなければなりません。sironekotoroさんも理解していただいていますが、第3章では、split関数も、配列も、ハッシュも、ループ構造も、正規表現も使えず、ただindex関数とsubstr関数を使って問題を解かなければならないというわけです。じっさい、ぼくはあきらめて、sironekotoroさんのブログから回答をいただきました。いうことで、ここではsironekotoroさんの考え方だけいただいて、いちおうぼくのオリジナルのプログラムを書いてみます。$monthの次に出てくる空白のオフセットを探す。"英語で$monthは$num月のことです。";ではまず、12月で実行してみます。./monthName3.pl英語でDecemberは12月のことです。[sample]$いいですね。次にプログラムの中のリテラルを変更して、Marchに戻して実行してみます。$monthの次に出てくる空白のオフセットを探す。"英語で$monthは$num月のことです。