はじめに
最近、言語の型について語っているブログをよく見かけます。
便乗するつもりはないですが、前々からJava/C# からRubyに乗り換えて感じていることを書きたいな〜と思っていたので、このタイミングでちょっと書いてみることにします。
今回のエントリはあくまで僕個人が感じていることを書くだけであって、別に言語の優劣を述べようとしているわけではありません。
そもそもプログラマ個人のバックグラウンドや知識、スキル等々によって感じ方や見解は異なってしかるべきだと思うので、その前提で読んでもらえればと思います。
僕のバックグラウンド
まず、最初に僕のバックグラウンドを紹介します。
- この業界に入って最初の3年ぐらいはJavaをよく書いていた。
- 最後に使ったのは Java 5.0 + Struts + Spring + Hibernateとか、そういう時代。
- 前職ではC#/ASP.NETをよく書いていた。
- キャリア的には5年ぐらいだったけど、悲しいことにずっとC# 2.0止まりだった。
- 型推論とかLINQとかは結局実務では使わずじまいだった。
- Rubyを本格的に使い始めてからは今で1年ぐらい。
- やっと中級者と名乗れるかなと思うぐらい。
- 使っているエディタはVim。
あと、前職ではVBScriptやJScriptを使ってお助けプログラムみたいなものはよく書いていました。
Ruby以外のスクリプト言語の経験が皆無、とかいうわけではないです。
JavaやC#が懐かしくなるところ
リッチなIDEがある
言語の機能そのものよりもEclipseやVisual StudioのようなIDEが恋しくなるときがあります。
IDEが恋しいときはこんなことをやりたいときです。
- ブレークポイントを付けてデバッグ実行したい
- 変数やメソッドの定義元にジャンプしたい
- 変数名やメソッド名を一括でリファクタリングしたい
もちろん、Vimでもプラグイン等である程度カバーはできるのですが、標準機能で簡単に実現できるのはIDEのメリットかなと思います。
また、RubyにもいくつかIDEがあるようですが、僕はまだちゃんと使ったことがないので詳細に比較することはできません。
デバッグ実行は激しくハマってしまったときの重要なツールになるので、Rubyの開発環境でも早く改善しないといけないな〜と思っているところです。
2015.10.3 追記: RubyにもRubyMineがあります!
IDEが恋しいと書きましたが、現在はRuby用IDEのRubyMineを使っています。
有料ですが、お金を払う価値はあるとても便利なIDEです!
詳しくはこちらの記事をご覧ください。
ライブラリやフレームワークのバージョンアップ時はコンパイラチェックがほしい
後方互換性のない変更点がライブラリやフレームワークのバージョンアップに含まれる場合はコンパイラのチェックがあるとうれしいなと思います。
Grep検索や自動テストを駆使すればある程度のところまではカバーできますが、コンパイラがエラーを出してくれる方が精神衛生上安心です。
タイポで変にハマるときもある
当然と言えば当然ですが、Rubyはタイポしていても実行するまで分かりません。
よくわからないエラーの原因を調査していったら、実は自分のタイポが原因だった、ということはたまにあります。
Rubyでも意外といけるじゃんと思ったところ
大規模なプログラムで大事なのは言語の選択よりもプログラマのスキル
大規模なプログラムや他人の書いたコードを変更するときは、JavaやC#の方が安心できるんじゃないかと思いましたが、そのあたりはRubyでも問題ありませんでした。
そもそもソニックガーデンのプログラマが書くコードはどれも読みやすくてDRYが徹底されているので、「直すのはたぶんここだな」というポイントさえ見つければ、たいてい問題なく変更が完了するからです。
むしろ、JavaやC#で書かれた小さなプログラムであっても、スキルに難のあるプログラマが書いたコードを変更するときの方がはるかに苦痛でした。
変数名やメソッド名の自動補完はVimでも十分
Rubyを始める前はVisual Studioのインテリセンスのような自動補完機能が無いとコードを書くのが大変なんじゃないかと思っていましたが、この点はVimの自動補完機能(Ctrl + P)でも十分でした。
Vimにはもっとリッチな自動補完用のプラグインがありますが、設定が悪かったのか僕はあまりしっくりこなかったので、今はVim標準の補完機能を使っています。
型情報がコードになくてもコードは読める
ケースバイケースなので絶対ではありませんが、コードに型情報がなくても他人の書いたRubyのコードは読みやすいと思います。
むしろ、"IList<User> users"のように自明な型名をつけるぐらいなら、"users"とだけ書けば良いRubyの方が読みやすいです。
またコードを書くときも、型情報がコードに出てこないので、それがかえってわかりやすい変数名やメソッド名を考えるための暗黙的な強制力になっている気もします。
ただし、予備知識が全くないライブラリのコードを読んだりするときは「ここにはどのクラスのオブジェクトが入るんだ?」と分からなくなることもあるので、型情報を付けてほしい場合もあります。
Rubyの方がいい!と思ったところ
IDEの起動やコンパイルの待ち時間がなくなった
JavaやC#を書いていた頃はIDEの起動やコンパイルの待ち時間が長いことがかなり大きな不満でした。
が、会社から支給されていたのがへっぽこPCだったという理由も大きかったと思います。
逆に今使っているマシンはかなり高性能なので、単純にRubyの方が軽いと断言することはできないと思います。
実際rakeタスクを起動したり、Railsのassetsをコンパイルしたりする時間は結構長いです。
ちなみに、待ち時間でついTwitterを見たりしてしまうぐらいの時間を僕は「長い」と定義しています。
DSLやテストコードのスタブ/モックが柔軟に書ける
Rubyのような動的な言語だと、事前にメソッドがなくても実行時にこしらえると言うことが可能です。
たとえば以下はFactoryGirlというテスト用のデータを生成するライブラリのコードです。
このコードにある"email"や"name"はRubyの構文上はメソッドです。
ですが、プログラマはどこかで事前にemailやnameといったメソッドを定義しておく必要はありません。
ライブラリが「未定義のメソッドはモデルの属性と見なす」といったルールで動的にメソッド呼び出しを処理してくれます。
結果として、「あたかも設定ファイルのようなRubyプログラム」が書けるわけです。
FactoryGirl.define do factory :user do email "hoge@fuga.com" name "hoge" password "xxx" password_confirmation "xxx" end factory :blog do title "My blog" content "Lorem Ipsum" end end
また、テストコードのスタブやモックもJUnitやNUnitを使っていた時代に比べてかなり簡単に書けます。
twitter.stub(:status).and_return({id: 123, tweet: 'テストなう'})
もっとも、このあたりはイマドキのJavaやC#なら色々と便利なやり方があるんだと思いますが。
便利なライブラリの導入が簡単
RubyやRailsには便利なGem(Rubyライブラリ)がたくさんあります。
もちろんJavaやC#でもたくさんありますが、いくつかのGemでは「これはスゴすぎる!!」と驚きました。
たとえば、kaminariというGemを使えば、ControllerとViewを数行変えるだけでWebのページング処理が実現できます。
# controllerの変更点 @users = User.order(:name).page params[:page]
# viewの変更点 <%= paginate @users %>
他にも「導入するだけでOK」とか「設定ファイルを変更するだけでOK」みたいなGemがよくあります。
このあたりはRubyの柔軟性がなせる技なんじゃないかと思います。
その他Rubyに乗り換えて感じたこと
デバッグ時にライブラリのコードを読むようになった
Rubyはスクリプト言語なので、ほぼすべてのプログラムをテキストファイルとして読むことができます。
なのでライブラリが思ったように動かないときはライブラリのコードを読んで原因を調査することが多くなりました。
JavaやC#でもオープンソースプロダクトであればコードを読むことはできるのですが、jarやdllだったりするのでついついドキュメントやネットの情報ばかりを追いかけていました。
まあ、これは習慣的なところも大きいので必ずしも言語の違いが原因とは言えないですけどね。
Rubyはプログラマひとりひとりの存在感が大きい
便利なGemを初めて使うときはたいていそのGemが置いてあるGitHubリポジトリに一度はアクセスします。
GitHubページを見ると、そのGemの作者やコードのコミッタの情報がすぐ目に飛び込んできます。
Javaを使っていた頃は「Apacheプロジェクト」「Jakartaプロジェクト」というなプロジェクト名でライブラリが提供されていたり、C#だとそもそもオープンソースライブラリの数自体がJavaやRubyよりも少ない印象だったりして、あまりプログラマ個人の存在を意識することはありませんでした。
なので、Rubyを使っていると、「この人はすごいRubyプログラマだな〜」と感じることが以前に比べてずいぶん増えた印象です。
そもそも、RubyのパパことMatzさんの存在感がかなり大きいですもんね。
Railsはカンタン、ではない
Ruby on Railsは簡単なフレームワークだとよく言われていますが、YESかNOで答えろと言われたら、僕はNOだと思っています。
確かに、単純なブログアプリやマスターメンテナンス画面を作るだけなら簡単ですが、実務で作るプログラムはそんなに単純ではありません。
Railsを始めた最初の頃はサンプルコードに載っていないような、ちょっとひねった仕様を実現するのに結構苦労しました(というか今も時々苦労してます)。
あと、実務でコードを書くときはRails単体ではなく、かならず周辺のGemも必要になってきます。
Gemも確かに便利なのですが、サンプルコード以外のことをやろうとするとやっぱり、「はて、どうやるんだ、コレ??」と悩んでしまうことが多いです。
Railsやよく使うGemに本当に精通している人なら爆速で作れると思いますが、そうでない場合、このあたりはどんな言語やフレームワークを選んでも結局大差ないのかも、と思ったりします。
Rubyは書いてて楽しい
これは完全に100%主観であることを分かった上であえて書きますが、僕はやっぱりRubyは書いてて楽しい言語だと思います。
楽しいというか、使えば使うほど手に馴染む革製品のような良さを感じます。
なので、多少のデメリットはあっても「好きだから許す」と思いながらRubyを使っています。
まとめ
というわけで今回はJava/C#からRubyに乗り換えて感じたことをいろいろ書いてみました。
最初に書いたように、プログラマ個人のバックグラウンドや知識、スキル等々によって感じ方や見解は異なるので、人によっては「あんたは何を言ってるんだ」と思うようなところもあったんじゃないかと思います。
しかし、すべての言語において隅から隅まで精通している人なんていないはずなので、こういう話は誰が書いても多かれ少なかれツッコミどころが出てくるんじゃないかと思います。
まあ、宗教戦争を巻き起こしやすいので、言語の根源的な優劣を決めつけるような書き方は避けるべきですけどね。
ではでは今回はこのへんで。
このエントリがRubyに乗り換えようと思っている人の何か参考になれば幸いです。
あわせて読みたい
「動的型付言語は使い物にならない」か? - give IT a try
Rubyを使い始める前に同じようなテーマで書いてみたエントリです。
僕の当時の想像と実際がどう違ったのか比較してみると面白いかもしれません。