そろろろRailsについて本音を書いてみるか

最近の大田さん@mixiのところで、Rubyについて考察する機会があったのと、よういちろうの考えと同じことを思っていたので、たまには本音で書いてみる。
Railsで、最も良いところは、テストの雛形も自動的に作ってくれて、テストの敷居を下げてくれてるところだと思う。なのに、それについて触れる人があまりにも少ないような気がする。一応、私は、1年半以上、はてなのキーワード検索で毎日Railsについては調べているので、はてなRailsについて書いている人の記事はたいてい見ています。
理由は、いくつか考えられますが、私の読みだと、テストが当たり前の人にとっては、当たり前すぎてわざわざ書く意味がないし、そうではない多くの人にとっては、ほとんどテストは書いていないんじゃないかな。
実は、テストを書くのは結構工数かかるんですよ。スクリプト言語は、コンパイラがミスを教えてくれることはないので、Javaと比べると、より多くのテストを書く必要があります。でも、そんな話ほとんど聞いたことないですよね。
RailsJavaに対して生産性が高いっていっているのは、テスト工数が見積もりからもれている可能性が高いんじゃないかと思う。テストなしでも困らないような単純なアプリを作るのには、それでも問題ない。テストが必要となってくる程度の複雑なアプリを作る場合には、Railsのテストの工数はそれなりにかかると思う。
後、よういちろうに言っておくと、Seasar2では、S2Unitを使って、テストメソッドごとにデータを用意できるから、データベースを使ったテストは、Railsよりやりやすいと思う。ただ、テストの雛形を作ってくれるのは、Railsのほうがずっと親切。
後、デバッグの環境は、Javaに比べて貧弱だと思う。Railsでデバッグをする7つの方法を見てほしい。IDEでソースにブレークポイントを設定(ソースコードを書き換えるのではなく)して、ステップイン、ステップオーバー、メモリの状態を見たりなんてのに慣れているJavaから比べると、すっごく大変に見える。テストをきちんと書けば、デバッグは必要ないという人もいるかもしれないけど、デバッグでしかわからないこともどうしてもある。デバッグが必要なほど複雑なプログラムだと、コストが結構かかるだろう。
後、この後の話は、RailsというよりRubyRubyというよりスクリプト言語のことなんだけど、他人の作ったソースコードを読んだり、利用したりするのは、スクリプト言語は、Javaと比べてつらいと思う。型の情報がないから。標準ライブラリのように使い方が判っているやつならいいんだけど。
自分で作ったやつは型がなくても大丈夫なんですよ。自分で知ってるから。でも、時間がたつとそれも怪しい。だんだん忘れていくからね。
また、型情報がないと、安全にリファクタリングをすることは難しい。grepで一括変換できるなんて状況は限られているから、スクリプト言語で効率よく、リファクタリングするのは難しいはず。
作り捨てなら良いけど、メンテナンスが必要になってくる場合は、リファクタリングは必要ですよ。
結局、テストがあまり必要にならない規模で、デバッグリファクタリングをあまりやらないなら、Railsは生産性が高いと思う。でも、それなりの複雑性が出てくるとテストがより多く必要になってくるので、生産性はJavaとあまり変わらなくなってくるはず。
小規模な開発だとRailsJavaより圧倒的に生産性が高いかというと、今のJavaには、HOT deployのできるSeasar2がある。フレームワークのできは、SAStrutsのドキュメントを見ていただければ、Rails同様の生産性が出せることもわかってもらえると思う。
パフォーマンスが普通に作っても出ることは重要ですよ。後からチューニングが必要になるとそれだけ工数がかかってしまうから。
追記:
デバッガに関してRails2.0だともっと良いやり方があるようです。変数の状態が見れるかどうかは書いてないけど、きっと大丈夫でしょう。ステップイン、ステップオーバー、変数の状態がみれる、これだけあれば、十分ですね。
追記2:
今回の記事を丁寧にフォーローしてくださった方がいるので、ぜひあわせて読んでください。
http://www.rmake-labo.com/akasata/articles/show/252
http://d.hatena.ne.jp/moro/20080111/1200046589
後、私の書き方が悪くて誤解されている方が多いと思いますが、スクリプト言語のソースが読みにくいと書いているつもりはありません。他の人の書いたソースを追いかけていくときに、型情報があったほうが、情報が多い分追っかけやすいということです。
また、他のクラスを利用するときに、メソッドの引数に型があったほうが、何が渡せるかより明確だということです。
後、Rubyは大クラス主義で、クラスを渡り歩く必要があまりなく、Javaは小クラス主義で複数のクラスを渡り歩く必要が多いという太田さんとこの話しも考えさせられるところがあり、もう少し議論してみたいところです。大クラス主義と小クラス主義の話が本当なら、Rubyは他のクラスをJavaほど使わないので、型がなくても気にならないということかもしれません。
でも、Javaの方が読みにくいよという意見もあるでしょう。
まず、この記事を読んでください。確かにJavaはうざく見えるけど、これは、Javaの話ではなく、Struts,Spring,Hibernateの話です。Seasar2でかけば、


@Execute(urlPattern = "edit/{id}") String edit() {
person = jdbcManager.from(Person.class).id(id).getSingleResult();
return "edit.jsp";
}
で、Railsだとこんな感じ。

def edit
@person = Person.find(params[:id])
end
やっぱJavaの方がソースコードが多いジャンと思われる方もいると思いますが、今のSeasar2は規約は最小限にして後から見た人のために、ソースを追うための必要な情報を残すようにしています。この辺は、ポリシーの違いですね。
ちなみにStruts,Spring,Hibernate版はこちら

public ActionForward edit(ActionMapping mapping, ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws Exception {
PersonForm personForm = (PersonForm) form;
PersonManager mgr = (PersonManager) getBean("personManager");
Person person = mgr.getPerson(personForm.getId());
personForm = (PersonForm) convert(person);
updateFormBean(mapping, request, personForm);
return mapping.findForward("edit");
}
PersonManagerクラスは他で定義されているし、getBean()、convert()、updateFormBean()というメソッドも他で定義されているはずなので、実質はさらに増えます。これはうざく感じるとおもいますが、これを見て、これがJavaなんだと思っちゃだめです(笑)。

SAStruts rc3リリース

SAStruts rc3をリリースしました。

リリースノート

  • Bug
    • [SASTRUTS-4] - ダウンロードで実行メソッドの戻り値をnullにするとぬるぽになる

ダウンロードのサンプルも追加しました。

SAStrutsのダウンロードはこちら。
http://sastruts.sandbox.seasar.org/download.html
また、今回のリリースのにあわせて、正式リリースの予定も若干変更します。18日の午後にSandbox卒業を申請して、19日に正式リリースするようにしたいと思います。
よろしくお願いします。