Railsのメリット
ひがさんがRailsのメリットについて書かれていたので、僕も反応してみる。
RailsとRuby、ひいては動的なスクリプト言語のメリットだと僕が思うところを書いてみます。以下は、おまえが知らないだけで実はJavaにもあるぞ、とかかも知れないけどとりあえず書く。
古き良き(!?)shellを活かしている
複雑な作業でも、シェルとして実行してしまえば簡単。一回書けば、あとはヒストリを検索して呼び出せば一瞬で再実行できる。それはshellの良さだけど、そのシェルの良さを認識して、rakeというツールの力で活用しているのはすごいと思う。
というか、たぶん僕はIDEが嫌いなのだと思う。というか、マウスが嫌い。
だから、WindowsでRailsを使っている人は、申し訳ないけどRuby on Railsの魅力30%くらいはダウンしてると思う。
フレームワーク自体を拡張することを前提としている。
前述のように僕はJavaのWebフレームワークは全然知らないけれど、たぶんJavaであるからには、それぞれのプロジェクトでフレームワーク自体に手を入れることは想定されてないんじゃないかな?Railsでは、そういうことはしょっちゅうある。好みの問題だけど、僕は好き。プラグインもたくさんあるし、rakeタスクを追加するのは楽しくて癖になる。
freezeの機能も素敵。freezeそのものはそんなに重宝するというわけではないけど、その思想が好き。ひとつのシステム上にRailsのバージョンが異なるプロジェクトが混在できるし。
インタラクティブシェル
僕はターミナルの一枚で常にirbを実行していて、何か疑問があるとすぐにirbで試している。正直、マニュアル調べるよりこっちのほうが早い。これも好みだけど。
あと、メソッドの一覧が知りたいときとかね。「えーと、Hashって、each系のメソッドって何があったっけ?」なんて思ったら、irbで
irb(main):001:0> Hash.instance_methods.grep /each/ => ["each", "each_value", "each_key", "each_with_index", "each_pair"]
てな具合。実際は、.irbrcでinstance_methodsをaliasしてるから、
irb(main):001:0> Hash.im.grep /each/ => ["each", "each_value", "each_key", "each_with_index", "each_pair"]
下手に検索するよりこっちのほうが早い。screenの画面切り替え(ショートカットはT)でirbに行って、試して、またすぐにemacsに戻る。
RubyのirbとかperlのperlshみたいなものをJavaで作るのって、技術的にはそんなに難しく無いと思うし探せばあるんだろうけど、広く使われている話は聞かないね。僕が知らないだけ?
実際、大学の授業でJavaをやらされていたときは、手製のjavaeっていうコマンドを作って使っていた。これは、コマンドラインから入力された一行プログラムを、例のstatic public void mainの中に入れて、packageは片っ端からimportして、コンパイルして実行するっていうインタラクティブシェルみたいなスクリプトだった。結構便利でよく使っていた。確か実装したのはPythonで、大学のマシンはかなり速いMacだったから、一行ごとにコンパイル実行でも使えてた。富豪。
型がわからない事はデメリットか?
型がわからない事はデメリットだといっている人は、Javaの発想から抜け出せていないと思う。Java脳でRubyを考えたら不便だと思うに決まってる。たぶん逆も然りだけど、Ruby脳の僕にはよくわからない。
大事なのは、型じゃなくて意味。型から変数の役割を想像するのではなくて、変数の役割から型を想像すべき。だから、コード自身が意味を語るようなプログラムを書くべき。これはある意味制約であるけど、ポジティブな制約だと思う。
RubyとRailsの悪いところ
公平のために、僕が思うRubyとRailsの悪いところを書いておく。
unexpected nil object エラー。
これは一度発生すると厄介な場合が多い。まぁJavaにもNullPointerExceptionがあるから似たようなもの・・・なのかな?
まだ実行に移してはいないけど、アプリケーションレベルのコードでメソッドからnilを返すのは辞めるべきだと思ってる。結果が「ない」ことを示すのは別のオブジェクトにして、アプリケーションコードのメソッドがnilを返したら即エラー、みたいな機構にするのがいいと思う。nilオブジェクト追跡みたいなライブラリを作ろうと思ってるくらい。
デバッガが遅い。
Rubyでは、set_trace_funcっていうメソッド(インタプリタへのデバッグAPI)を使ってデバッガとかトレーサとかが実装されているんだけど、これが遅い。スクリプトの1行ごとにコールバックを呼ぶのだから遅いのは当然なんだけど、trace実行が10倍速ければRubyのデバッグは違う次元に行ってると思う。
デバッガとかプロファイラが言語自身で実装できるのは言語実装者の立場からするとエレガントだし楽だ。僕も(お勉強的な)専門は言語処理系だからそれは非常に理解できる。けども、現実を考えると、やっぱりデバッガとプロファイラはがんばってCで作りこむべきなんだよなぁ・・・。これは難しいところ。
クラスの動的定義
うーん、メソッドの動的定義はあまり気にしないし自分でも書くのだが、クラスの動的定義はちょっとなじめない。理由はよくわからない。なぜか。