Rubyの落とし穴
しかし、Rubyにはいろいろ落とし穴がある。というわけで、講義を通して次のような落とし穴にはまった。
なお、筆者なりの解決案をちょっと考えてみたが、いずれも確かに問題かも知れない。また、現在のワークアラウンドについては、増原氏のセッション資料(PDF)に示されているので、そちらも参照のこと。
end忘れ
これは確かにRubyの落とし穴だ。
特に、学生はあまりきちんとインデントを書かないため(プログラマ教育をしているのではないことに注意)、endを忘れた場合に、エラーメッセージがほとんど役に立たない(し、そもそもエラーメッセージを読まないのが問題だそうだが、これもプログラマ教育をしているわけではないので仕方がないのだろう)。
ちなみに、この問題については、少しでもRubyを使うと必ずひっかかるので、いくつかの実験的な解消案が出ている。
例えば桑田氏によるMismatched-Endは、ifに対してendif、forに対してendforといった対になるendを置けるようにすることで、記述、エラーメッセージ双方で、より明確になるように図っている。
また、RubyKaigi 2007では山野ゆき菜氏によるインデントの対応をチェックするRubyEndというパッチが紹介されている(注2)。実は、RubyEndについて、まつもと氏は「その後の消息を知りませんね。取り込んでもよいと思ってたのに。」と書いている。ぜひ、山野氏はruby-devで提案してください! (パッチのREADMEにはRuby'sライセンスと書いてあるから、勝手代理でもいいのかなぁ?)
ロードの優先順
Rubyのrequireは標準ライブラリをカレントディレクトリのスクリプトより優先的にロードするため、findのように標準ライブラリと衝突するファイル名をつけると、まったく予想もしないエラーとなる。
これは多分セキュアかどうかといった問題なのでRubyの動作を変えることはできないのではないかと筆者は思うが、irbなどでロードするときは、常に「require './find'」のように、「./」を付けるのが良いのではないだろうか。ちょうど、意識的にカレントディレクトリに作成したシェルスクリプトを実行するときと同じような方法である。
全角文字の混入
例えば全角の記号(「”」など)の混入によるInvalid charエラーである。もちろん、全角空白も問題である。
さらに、日本語を含む文字列のinspect
メソッドは8進数にデコードした文字列を返すため、評価結果に文字列そのものを利用すると、irbの結果表示が(一般的には)読めない文字列となり、これも困るとのことだ。
String#inspect
を書き換えるといった方法はとれるだろうが、それをどう組み込むかという問題もあるし、これはなかなか難問である。
見出しと配列を同時にプリント
標準出力へ引数を印字する関数的メソッドにはp
、print
、puts
の3種類があるが、1行に文字列とnilを含む配列を並べて出力しようとするとうまくいかない。pは配列をうまく出力するが、各引数の間に改行が入る。putsは配列の要素ごとに改行が入る、printはnilを無視するなどで、うまくいかない。
これについてはArray#inspect
の呼び出しとprint
の組み合わせが良いかなと思うのだが、レシーバを指定したメソッド呼び出しは教えない前提のため、そうはいかない。
論理演算子の優先順位
Rubyistであれば、or、and、notの3つの演算子を利用しないものだが、つい使ってしまってはまってしまうことはあるらしい。例えば次のリストは、実行するとSyntaxError例外となる。
false || not(true)
ワークアラウンドは、||、&&、!を使うこと。Cと同じ演算子なので、こちらを教えれば良いので大した問題ではなかったとのことだが、最初はとっつきやすい英単語のほうを使って教えられたのだろう。