数年ぶりにガッツリRailsで開発するプロジェクトに参画している。その中で感じたことを徒然なるままに書こうと思う。なお、「それRailsじゃなくてRubyの話っしょ?」という内容も多分に含んでいると思うが、そこはご勘弁。
目次
やっぱり便利だ
なんだかんだでRailsは便利だと改めて感じた。筆頭はやはりActiveRecordだろう。特にnamed scopeやvalidationの書き味は慣れるともう手放せないレベル。他のフレームワークにも同様の機能はあるんだろうが、書きやすさや見た目のスッキリ度となると、Railsには遠く及ばないと思う。まあこのあたりはRubyのおかげなんだろうけど。
Railsはフルスタックフレームワークなので、テストのサポートも手厚い。rails newしたときからテストが可能だし、テスト用のスキーマが別れている・自動でロールバックするとか、至れり尽くせり感がある。またマイグレーション機能も標準装備なので、基本このあたりで困ることがない。PythonのSQLAlchemyを使っていたことがあるが、railsと同様のレベルではないので少しストレスを感じた。もちろん、自力で書くor設定していけばそれっぽくは動くが、そこに至るまでの作業が面倒っちゅうのがある。
アップデートがつらい
よく言われているようにRailsはアップデート周りがつらい。なんでだろうなー?と考えてみて、自分なりの答えを出してみた。それは「コミュニティ」だと思う。Railsコミュニティって革新的(保守的の反対)だと思うのだが、わりとイケイケドンドンで変更入れてきたりする。もちろん後方互換性は保ちつつだけど、なんだろう、保ってんだけど、わりと早めについて行っとかないとすぐに辛いことになる。メジャーバージョンも比較的すぐあがる方だと思うし。
で、Railsがそういう感じなので、その界隈も、例えばgem周りなんかも同様に革新的だったりする。rubygemsによるエコシステムは発展しているのだが、そこがある意味にネックになったりして、bundle updateでバージョン依存を解決できずに詰むというのもよくある話。「Railsをアップデートしたいけど使用しているgemのバージョンが上げられない」みたいな話。ひとつのgemにベンダーロックインされる感じというか。
そうならないように「gemは本当に太いものだけ使用する」とか「なんかあっても自分たちでフォークして直す」とか、そういうことはあらかじめ検討しておいたほうが無難。
スキルが必要
いつ頃からか、「Railsは初心者にも簡単」といった受け売りになったような気がするが、Railsは基本的には難しい・スキルを要するフレームワークだと個人的には感じている。よく言われるように「レールに乗っている間は簡単。レールから外れると途端に難しくなる」のがRailsだと思っていて、しかも「レールから外れるのは結構すぐ」起こることだと思っている。
そもそもレールに乗っている程度のアプリってTODOアプリとか簡単なブログアプリとか、せいぜいチュートリアルレベルのもんだと思っている。ちょっとでもまともなサービスを作ろうとしようものなら、簡単にレールから外れる。外れざるを得なくなるというか。やっぱりモノづくりって結構泥臭いもんですからねー。
で、レールから外れたときに急にスキル(技術力)が必要になってくる。設計や実装の力が。典型的な一例を上げると、レイヤー不足になるのでService層を追加するとかそういうこと。こういうのって、動画サイトでプログラミング学んでます!って人にはちょっとレベルが高い話になってくる。なので「できない」「やらない」になり、コードは荒れる。(そうでなくても荒れてる可能性もあるが)
すぐにレールから外れることが分かっているなら、「そもそもレールを引かないでほしい」と思う一派(スキルがある人たち)が当然現れるわけで、そういう人たちがRailsから離れている(いった)んじゃないかなと個人的に思う今日このごろ。
設計パラダイムが古くなる
これはRubyの話になってしまうが、「関数がファーストクラスオブジェクトではない」というのが現状のプログラミング界隈においては非常にディスアドバンテージになっていると思っている。今、メジャーな言語で関数がファーストクラスオブジェクトじゃない言語って私は知らない(知らない私が無知なのかもしれないけど)。
差分プログラミングという言葉があるが、これは共通部分は当然何らかの方法で括るとして、差分をどう埋めるか、ということにフォーカスした考え方だ。Java一辺倒だった時代は、基本的にはそれを縦の継承関係で埋めようとしてきたわけだ。GOFのデザインパターン(死語?)でいうTemplate Methodsとかが有名。大雑把に言うと、縦で差分を埋めようとしてきたが、現在はその方法論は「(ピタッとハマるケースがほぼ無いので)やめておこう」に近しい時代になっていると思っている。継承→実装→コンポジション→関数型という流れだと理解している。
というわけで、Javascript見りゃ分かる話だが、「差分はコールバック関数で埋める」という手法が一般的な世の中になっている。Rubyはこれができない。厳密にいうと「できなくないが、普通じゃない」みたいな。そうです、ブロックやProc/lambdaがあるんだけど、ちょっと書き味が独特のものとなってしまうのだ。ブロックはご存知の通りああいう感じだし、Procもcallしないと呼び出せない。.call呼ぶっていうのはちょっとなーと思ってしまう。
当時は先進的だなあと思っていたが、今となっては「ちょっと変わった言語」みたいな位置付けになってるのかもしれない。
ActiveSupportこそRailsなのかもしれない
と思うようになる。Railsがフレームワークのくせに、あたかも言語・環境かのように捉えられるのはこのActiveSupportによる言語拡張なんじゃないかな。尋常じゃなく便利なメソッドがたくさん生やされてる。個人的には to_date
に一番お世話になってるかな。ふと素のRubyを使っている最中に、「あれ?あのメソッド無いの?」「ああ・・ActiveSupportだったのか・・・orz」ということが結構ある。
既存のクラスに便利メソッドをガンガン生やしていく姿勢こそザ・Railsといった感がある。理に適っている部分も多いと思うのだが、いかんせん動的型付け言語でこれをやられると、わりと困ったことにもなりうる。(後述)
Googlability(ググラビリティ)が低い
Rails初心者と一緒に開発しているとよく分かるのだが、RailsはとにかくGooglability(ググラビリティ)が低い。Googlabilityとはグーグル検索のしやすさ。何か分からないことがあったときに、グーグルで検索しやすい・検索結果が豊富なものほどGooglabilityが高いということになる。Railsはこれが低い。
例えばActiveRecordを例に取ると、動的に生やされたメソッドfind系メソッドとか。find_by_user_id
というメソッドを使用している箇所を初学者が見つけたとしよう。「このメソッド、どこで定義されているんだろう?」とソース内をgrepしても出てこない。なんじゃこれ?と思ってGoogleで検索してみる。それらしいのが出てこない・・・。い、いったいどこの誰が定義しとんじゃーー!?というようなことがよくある。
あと、単純に「なんと検索したらいいか分からない」とか「え?そんなことできるんですか??」ということもメチャ多い。機能が多すぎ・便利すぎなので気付けないんだよね。チュートリアルにも書いてないし。API Docには載ってても、いきなりそれ見ないし。
IDEのサポート(あまり)受けられない
Rubyは動的型付け言語であり、かつ構文の自由度が高いこともあって、相当構文解析器泣かせみたいだ。というわけで、LSPがあっても、ロクに動かない。動くけど今一歩である。RubyMineが一番まともで、これはかなり強力だが、いかんせん世の中のデファクトスタンダードはVSCodeだろうから・・・。PythonならVSCodeでもかなりLSPの恩恵受けられるけど、それと比べるとRubyはいまいちなんだよな・・・
JetBrainsのFleetでもRubyはサポートされてないし、たぶんこれからもサポートされないんじゃないだろうか・・・。世の中は静的型付けが主流だと思うので、まあ仕方ないよね。アノテーションによる型ヒント使うぐらいだったら他の言語使うようになるだろうし、個人的にはこれ以上状況は良くならないと踏んでいる。
総じて
色々と書き殴ったけど、Railsは1.2から使ってるし好きだし応援したいと思っている。でもイチから何かを作るときは・・・もう選択しないかもしれない。(という駄文。)
関連する記事
- Rails用のgemを作成する手順 (Rails 4.0以降)
- 【Rails】リロード時に特定の処理を実行する
- Railsアプリを『浅く』パフォーマンス・チューニングしてみる(その1)
- Testing like the TSA by David of 37signals(和訳)
- simple_formとTwitter bootstrapで作る俺流鉄板Railsアプリ(その1)