2016年2月16日
Railsの基本理念 : Railsの生みの親が掲げる8つの原則
(2016-1-19)by David Heinemeier Hansson
本記事は、原著者の許諾のもとに翻訳・掲載しております。
(訳注: 2016/3/2、頂いたフィードバックをもとに記事を修正いたしました。)
Ruby on Railsは最近、急激に注目を集めていますが、その原因はほとんど、この言語が斬新なテクノロジーとしてもてはやされたことと、タイミングにあります。技術的な優位性は時間の経過とともに失われますから、タイミングがよかっただけでは、一過性のブームに終わり、このムーブメントの隆盛は長続きしません。従って、「Railsがいかにして、適切な技術としての位置を維持し続けるるだけでなく、影響力とコミュニティを拡大し続けてきたのか」をより多くの人に説明していく必要があります。そして、その維持・拡大を可能にした/していく要因は、物議を醸すことさえあるRailsの基本原則にあると考えています。
この基本原則はここ10年ほどの間に進化を続けてきましたが、最も強固な柱となっているルールはやはり、公開当初から制定されているものです。これらがもともと独創性にあふれていることについて、私は特に何も言うつもりはありません。Railsの大きな功績は、プログラミングとプログラマの性質について様々な方向に広がっていた思考を1つにまとめて、強力なコミュニティを作り上げたことです。
さんざん考えた結果、以下に不肖私David Heinemeier Hansson(DHH)が Railsの最も重要な柱と捉えている、8つの基本原則を挙げます。
- プログラマの幸福度を最適化
- 設定より規約を重視する(CoC)
- メニューは”おまかせ”で
- パラダイムが1つではない
- 美しいコードを称える
- 統合システムを尊重する
- 安定性より進歩を重視する
- テントを押し上げる
プログラマの幸福度を最適化
RubyなくしてRailsは生まれなかったのですから、基本原則の最初の柱として挙げるのに唯一ふさわしいのは、そもそもRubyが誕生するきっかけとなった要因をそのまま流用したものでしょう。
Rubyが本質的に抱える異質性こそ、プログラマがこの言語を使って感じる幸福の基盤となるものです。それ以外にも存在する懸案事項、その多くは悩む価値のあるもので競合したりもしますが、こうしたものが、プログラミング言語やそのエコシステムが進化する際の原動力となってきました。
Pythonなら「あることを行うための方法はただ一つだけであることが望ましい」ことを誇りにするところで、Rubyは表現の豊かさと繊細さを大切にします。Javaにはプログラマの自己防御の仕組みが強制的に組み込まれているのに対して、Rubyは入門キットに首つり用のロープが含まれています。Smalltalkはメッセージパッシングの純粋性を深く掘り下げますが、一方でRubyは予約語や制御構文も貪欲に取り入れています。
このように、Rubyは他の言語と違う価値観を持っている点に特徴がありました。また、プログラマはその部分に幸福感を感じていました。この幸福の追求が、他のプログラミング環境と競合する一方で、プログラマの役割やプログラマに期待される行動様式についての認識の主流となっていました。
Rubyはプログラマの気持ちを認識するだけでなく、それをくみとって高めていくことを目指していました。例えそれが不適切だったり気まぐれだったりおふざけだったとしても。Matz(まつもとゆきひろ)氏が驚くほどの複雑さというハードルを飛び越えて(Rubyという)マシンを構築したのは、ほほえましいことであり、彼と一緒に仕事をしてきた仲間にとっても喜ばしいことでした。Rubyは一見、単純明快で美しい要素ばかりですが、実はその裏に、複雑に張りめぐらされた配線が隠されています。そこにたどり着くまでにはそれなりの代償を払ってきましたし(JRubyを作った人々に、このすばらしいオルゴールをリバースエンジニアリングするのはどんなものだったか聞いてみてください!)、だからこそRubyは称賛に値するものでした。
しかし私は、プログラミングとプログラマに対して新たなビジョンを提示することにのめり込み、Rubyに浮気していたのを封印するまでになりました。単に使いやすいだけではなく、個々の要素が美しいだけでもなく、技術上の大きな功績というだけでもありません。これはビジョンです。ある種のカウンターカルチャーです。既存のプロ向けプログラミングの型になじめず、その価値観に染まりたくないという人たちのための場所でした。
私はかつて、Rubyに関するこのような発見を指して、”私の脳みそにぴったりな素晴らしい器”と表現したことがあります。こんなになじめるものが世の中に存在するとは、思ってもみませんでした。というより、それをはるかに超えるものでした。「仕方なしにプログラミングをする」から「知的な実践と表現のモードが大好きになったからプログラミングをする」へと、私の価値観を大きく変えたできごとでした。これは” フロー状態への入り口 “であり、しかも自分の意志でそこに入ることができます。Csikszentmihalyi氏の著書をよくご存じの方には、このことの影響がどう言おうとも誇張ではないことがお分かりでしょう。
私はよく、Rubyが私の人生を変えたと人に話しますが、これは全く誇張ではなく、Rubyは私のライフワークとなりました。本当に思いがけないことでした。今ではすっかり、Matz氏の創ったこの言語を広めるのが私の天職だと思うようになりました。この深遠な創造物とその利点を普及させる仕事です。
ここまで読んで、ほとんどの読者の方は首をかしげて、うさんくさい話だなと感じておられることでしょう。私はそれで皆さんを責める気にはなれません。“プログラミングなんて単なるツール”と思っていた頃の私に、仮に誰かがこのような体験談を語ったとしたら、私だって首をかしげていたでしょう。宗教めいた言葉があまりに多用されているのを見て、笑い飛ばしていたことでしょう。多少あるいは大いに困惑する読者の方がおられたとしても、これが私の偽らざる気持ちです。
さて、ここまで語ってきた原則は、Railsにとってどのような意味があったのでしょうか。そして、この原則はRailsの進化とどうつながるのでしょう? これに対する答えを出すためには、次に説明したい基本原則、”驚き最小の原則”(PoLS: the Principle of Least Surprise)に目を向けるのがよさそうです。この原則は、公開当初のRubyを評してよく言われていたものでした。Rubyはプログラマの期待通りの動作をするべきです。この点はよくPythonと対比させて説明されます。
$ irb
irb(main):001:0> exit
$ irb
irb(main):001:0> quit
$ python
>>> exit
Use exit() or Ctrl-D (i.e. EOF) to exit
インタラクティブなコンソールを終了したいというプログラマの明確な要望に対応するために、Rubyはexitとquitの両方を容認します。これに対してPythonは、状況から(そもそもエラーメッセージを表示している時点で)対処法が分かっている場面だったとしても、要求を適切に処理する方法について、プログラマに細かいところまで指示を出します。これは、小さいながらもかなり明確なPoLSの例です。
Rubyコミュニティの中でPoLSを支持する人が減っていった理由は、この原則がそもそも主観的なものだからです。では、誰に対して最小の驚きとなるのでしょうか。まずはMatz氏でしょう。そして彼と同じ思考回路を持つ人々です。Rubyコミュニティが拡大し、驚きを感じるポイントがMatz氏とは違う人々の割合が増えるに従って、PoLSは、コミュニティ加入が無意味だからメーリングリストから脱退したいと考える人を増やした原因となりました。「Xという人物はYという行動に驚くかどうか?」という不毛な論争に発展することを恐れて、この原則が表立って語られる機会は次第に減っていきました。
では改めて、これがRailsとどう関係するのでしょうか。Railsは、(Matz氏に対する)PoLSと似た原則に従って設計されました。”(DHHの)満面の笑みの法則”については、かつて別の場所でまとめた言葉を以下そのまま引用します。「熟慮を重ねたうえで設計されたAPIは、何に対して熟慮したかは関係なく、私はそれを見て満面の笑みになります。」私がこんなふうに書くとほとんど笑えるほどの自己陶酔に見えるかもしれませんが、そんな私の第一印象を覆すのは、今でも難しいのです。
それでも RubyやRailsのようなものを作り上げてしまったのは、少なくともかなり自己陶酔的な試みだったと言えます。どちらのプロジェクトも、たった1人のクリエイターの頭の中から生まれたものです。ただし私はここで、私自身のモチベーションをMatz氏に投影していますから、ここで私の話の範囲をもう少し絞り込み、私が分かることだけ宣言しようと思います。私がRailsを作ったのは、自分自身のためでした。私自身が誰よりも早く、最高に満足して満面の笑みを浮かべるためです。これを皆さんに利用してもらえるかどうかは、自分で使ってみてどこまで自分の生活が楽しくなるかを見た結果に大いに左右されます。ウェブ情報システムの要件と要求について、日々苦しみつつも議論を深めています。
Matz氏と同様に、私も時として自分のこだわりに従い、バカみたいに長々とコードを書いてしまうことがあります。その一例がInflectorです。これは英語について、必要となるパターンや不規則変化を理解するクラスで、PersonクラスをPeopleテーブルに、AnalysisクラスをAnalysesテーブルに、CommentクラスをCommentsテーブルに、それぞれマップします。この振る舞いは今でこそRailsの要素として無条件に容認されていますが、公開当初私たちは、基本原則とその重要性に執着していたので、論争となり、その議論がものすごい勢いで炎上した時期もありました。
実装に要した労力はこれよりは小さいものの、同じぐらい物議をかもした例を1つ紹介します。これには驚愕にも近い感情が沸くかもしれません。それは、Array#secondからArray#fifth(それと、絶好の釣り針としてのArray#forty_two)として用意されたアクセサです。 これらのアクセサのエイリアスは、口うるさい支持者(からほぼ末端の市民まで)から「Array#[1],Array#[2],…Array[41]のように書けばいいのに」と強く非難されました。
しかし、今なら私は、どちらの形式でも笑顔でいられます。テストケースやコンソールでpeople.thirdに書き込みをするのが私は好きです。でもこれは論理的ではありません。効率的でもないのです。むしろ病的です。しかし、それでも私は笑顔になってしまいます。それゆえに、私は原理に満足し、自分の人生を豊かにでき、提供を始めて12年経つRailsに関する仕事をこれまで信じて続けてこられました。
パフォーマンスのために最適化するのとは違い、幸せのために最適化するのは大変です。幸せのためというのは、本質的にはほぼ非科学的な心がけです。ひどいフラストレーションを感じない限りは、重要ではありません。プログラマは予測できることに関して、議論し問題を解決しろと教わります。予測できることとは、明白な結論がある場合や、AがBよりも良いということが明確である場合です。
しかし、マイクロレベルでは幸福の追求を測ることは難しいですが、マクロレベルで観察することは非常に容易です。Ruby on Railsのコミュニティは、まさにこの追求のために集まった人たちなのです。彼らは、より良い、より充実した仕事をしていることに誇りを感じています。そのために、明らかな勝利を確信する気持ちが高まります。
ということで結論はこうです。幸せのための最適化をすることはおそらく、Ruby on Railsを形作ってきた一番の要因となります。そしてRuby on Railsは前に進み続け生き残っていくでしょう。
設定より規約を重視する(Convention over Configuration、CoC)
Railsの生産性に関する初期のモットーは、”君は美しい唯一無二の雪の結晶というわけではない”でした。これは、無駄な個人プレーをやめれば、平凡な決断で苦労することなく、重要な場面で仕事のスピードが増す、ということを言っています。
データベースの主キーがどの形式で記述されているか気にする人はいますか? ”id”か、”postId”か、”posts_id”か、”pid”のどれなのかを問題視する人はそんなにいるでしょうか? そして、これは再度、熟考するに値する決定でしょうか? いいえ、違います。
Railsの使命の1つは「Web用に情報システムを作成している開発者が直面する”繰り返される決定”という名の木が生い茂る、成長し続けているジャングルで、ナタを振り回す」ようなものです。一度きりで終わる決定もたくさんあります。もしそのような決定をあなたのためにしてくれる人がいれば、なおさらいいです。
設定から規約に移行することは、熟考をしなくてよくなるだけでなく、より深い抽象化を育ててくれる豊かな土地を提供してくれるということです。peopleテーブルにマッピングしたPersonクラスを使えるのなら、has_many :peopleとして宣言される関連付けについても同様のインフレクションを使うことができ、Personクラスを探すことが可能になります。いい規約というのは、広範囲に利益をもたらすことができるものをいいます。
しかし、専門家の生産性が高まる以上に、規約は初心者参入のハードルを下げてくれます。Railsの規約の中には初心者が知らなくてもいいものがたくさんあります。彼らにはその無知ゆえのメリットがあるのです。決まりに縛られずにすばらしいアプリケーションを作ることが可能だからです。
フレームワークがただの分厚い教科書であれば、それは不可能です。その新しいアプリケーションは何も書かれていない紙と同じように価値はありません。どこからどのようにして始めるかを導き出すのはとても労力のいる作業です。前に進むためにやらなければいけない、その戦いの半分は、どの糸を引いたらいいのかを探る作業になるでしょう。
何が必要になるかを全て理解している時でも同じことです。変化に対応するために、決まったやり方があるような場合、他のアプリケーションや今まで存在したものと同じか酷似しているアプリケーションを作って突進していくことも可能です。1つは全てのために、全ては1つのために存在します。この制限があることで高い知能は必要ではなくなるのです。
しかし、どんな場合でもそうですが、規約の力も危険を避けることはできません。Railsの規約は本当に細かいところまでこだわっているのであれば、既成のテンプレートを使えばアプリケーションを丸ごと構築できてしまうのではないかと考えがちです。しかし、アプリケーションを作るなら、それ独自の要素を持つべきです。それが全体の5%や1%でも、ないよりはマシです。
いつごろから規約から離れてしまってもよいかを判断するのは、難しい問題です。道から外れた特定の何かが、脱線の許可を得るのはいつでしょうか? 私は、美しい唯一無二の雪の結晶になりたいという衝動の大半はいい考えだとは思いません。そして、離脱したRailsの価値が評価されていません。しかし、全てを慎重に審査する必要もないのです。
メニューは”おまかせ”で
レストランに行ってどれがおいしいのか分からない時ってありますよね。何が”いい料理”なのか理解すらしていなくても、そのレストランのシェフに選んでもらえばおいしいものを食べることができるでしょう。これが”おまかせ”です。おししいものを選ぶのに、料理のエキスパートになる必要はありませんし、運に任せてメニューから料理を選ぶ必要もないのです。
このように別の人に自分の面倒を見てもらえることは、プログラミングの世界では、先ほど”設定より規約を重視する”で得たメリットとほぼ同じことなのです。ただし、こちらのほうがハイレベルな話になります。個々のフレームワークを最大限に使うにはどうしたらいいかということを考えるCoCでの”おまかせ”は、 どの フレームワークを使いどうやって組み合わせていくか、ということに注目します。
個々のプログラマに、存在するツールから選択する特権(という重荷)を与えてきた、プログラミング界でずっとあがめられてきた伝統とは相反することとなります。
“仕事には最善のツールを使え”という言葉は誰しもが聞いたことがあり、納得してくれるものでしょう。議論する必要もないほど初歩的なことに思えますが、”最善のツール”を選ぶということは、自信をもって”最善だ”と言って選択をするという土台に基づいています。これは見かけよりも難しいはずです。
これはレストランでメニューを選ぶ時の問題と似ています。フルコースの8品を全て自分で選ぶ時のように、ライブラリやフレームワークをそれぞれ選択する行為を切り離すことはできません。2つのケースとも、ディナーの内容を全て、もしくはシステムの全てを考えなければいけないことになります。
Railsでは、プログラマが自分のボックスからそれぞれのツールを選択するという労力を減らした、もっとすばらしいものを作りました。全ての人が使えるツールボックスです。メリットは以下のようにたくさんあります。
- 大勢が使用するほうが無難: Railsを同じデフォルトで使っている人が多ければ、共有できることが増えます。ベースは同じなので人に教えたり、手助けするのが容易になります。議論する基礎を既に持っていることになるからです。例えば、昨晩7時に放送していたテレビ番組をみんなが見ていれば、次の日にその話ができますね。コミュニティとしてより強いつながりができるのです。
2. 共通の基本的なツールボックスを人々が進化させる: フルスタックフレームワークとして、Railsは動的な部分も数多くありますし、それぞれが単独でどのように機能するのかと同じくらいに、それらがどのように組み合わさって機能するのかというのが重要になります。ソフトウェアの不具合はそれぞれのコンポーネントが原因ではなく、それらの相互作用の中で発生します。構成された複数のコンポーネントから、共通の不具合を緩和しようとみんなで取り組み、同じ状態で失敗するならば、不具合の回数を減らすことができるでしょう。
3. 交換は可能だが、必須ではない: Railsは”おまかせ”スタックである一方で、他のフレームワークやライブラリと取り替えることもできます。しかし、必須ではありません。つまり、時たま発生する相違に適した、明確で個人的なパレットをのちに開発することもできるということです。
Railsに来てRailsをずっと使用して、経験もあり腕のあるプログラマでさえ、メニューの中全てのものを気に入らないことは十分にありえます(もし、全てに満足している人がいるならば、それはRailsでまだ行き詰まっていないということなのでしょう)。彼らは勤勉にも別のものに交換し、それからみんなが監督し共有している他のスタックにいってみて、楽しんでいます。
パラダイムが1つではない
「まず中心となる1つの考え方を選んで、それに追従した論理的結論としてアーキテクチャの土台に辿り着く」という方法は、とても魅力的に感じられます。そうした規則には混同がないので、プログラマには輝く光に感じられ、自然と引きつけられるのも無理はありません。
しかし、Railsはそういうものではありません。きれいにカットされた1枚の生地ではないのです。言わば、キルトです。つまり、多くの異なる考え方やパラダイムから構成されているものなのです。通常、それらだけで、あるいは一対一で対比した場合、多くは対立しているように見受けられます。ですが、対立させることは私たちの目的ではありません。これは、単独の勝者を決めなければならないという、優秀な考え方選手権ではないのです。
RailsのMVC(Model、View、Controller)でビューを構築する際に用いるテンプレートを例に挙げてみます。私たちがこれらのテンプレートからコードを抽出できるようにするヘルパーは、デフォルトでは、単なる関数がたくさん詰まった大きな鍋にすぎません。しかも、1つの名前空間です。なんと衝撃的で恐ろしいことでしょう、PHPのスープのようです。
しかし、ビューのテンプレートで行われる多くの抽出と同様、「めったに相互作用を必要としない個々の関数を提示してくれる」という点においては、PHPの物事の扱い方は正しいということも主張しておきます。そして、このために、1つの名前空間、メソッドの大きな鍋が、合理的というだけでなく素晴らしい選択でもあるのです。
これは、私たちがビューを構築するとき、もっとオブジェクト指向なものを使おうとしないという意味ではありません。プレゼンタ(Presenter)とは「互いに依存している多くのメソッドやその下のデータを包括するところ」なのですが、そのコンセプトは時に、相互の依存関係によってまずくなったメソッドのスープを修復する完璧な手段になりえるのです。しかし、それがうまく合うことは一般的というより、むしろめったにないことだと広く証明されています。
比較する際、私たちは通常、オブジェクト指向における代表的な利点として、MVC層のモデルを取り上げます。オブジェクトに対し適切な名前を見つけ、コヒーレンスを増やし、そして結合を低下させることが、ドメインモデリングの楽しさです。これはビューとは全く異なる層なので、アプローチも異なってくるのです。
しかし、ここでもシングルパラダイムの定説には同意していません。Railsのconcern、すなわちRubyのミックスインの特殊化は多くの場合、個々のモデルの範囲を非常に幅広くするように使用されています。これが、関係するメソッドから、相互にやりとりを行っているデータとストレージに直接アクセスすることにより、ActiveRecordパターンとよく合うのです。
ActiveRecordフレームワークの基礎そのものでさえも、純粋主義者を不快にさせることがあります。私たちは、データベースへの直接のインターフェースに必要なロジックと、ビジネスドメイン/ロジックをミックスしています。境界が曖昧になっているのです。そう、それは、「ドメインモデルの状態を永続化するために、ある種のデータベースと事実上常に対話するウェブアプリのカタログを被せる」というのが実用的な方法であることが判明したからです。
イデオロギー的に柔軟なので、Railsはそうした幅広い問題に取り組むことができます。ほとんどの個々のパラダイムは、ある問題の特定の空間で非常によく機能しますが、それ以降でちょうどよい範囲を超えて適用される場合、厄介なもの、あるいは柔軟性のないものになります。私たちは多くの重複するパラダイムを適用することにより、脇を固め、背後を守っています。最終的なフレームワークは、それを可能としていた個々のパラダイムよりもずっと強く、より有能なものになります。
さて、プログラミングのパラダイムをたくさん持っているこのポリアモラスな関係には、概念上のオーバーヘッドという代償が伴います。Railsで楽しいプログラミングを行うためには、オブジェクト指向プログラミングをただ知るだけでは十分ではありません。同様に、手続き型や関数型のプログラミング言語を経験したほうが良さそうです。
これは、同様にRailsの多くの下位言語にも当てはまります。私たちは、たとえば「時折生じる複雑なクエリのためにSQLを学ぶ必要が出た」「ビューのためにJavaScriptを学ぶ必要が出た」といった人を保護するつもりはそれほどありません。少なくとも可能性が高いということはありません。
その学習負担の一部を軽減する方法としては、フレームワークのあらゆる側面を理解する前に、単に始めやすくし、本当の価値を生み出すことです。こうした理由があれば、私たちはすぐ”Hello World”に向かうものです。あなたのテーブルは既に準備が整い、前菜が並べられているのですよ。
ちょっとした真の価値を早い段階で与えることによって、私たちは素早くレベルアップするためにRailsを使おうとする人たちを応援します。障害ではなく、喜びとして、彼らが学習の過程で利用することを受け入れています。
美しいコードを称える
私たちは、コンピュータや他のプログラマに分かるようにというだけでなく、美しさから得られる満足感に浸るためにコードを書きます。見た目が美しいコードは、それ自体が価値であるとともに、大いに追求されるべきものです。美しいコードが他の事より常に優先だというわけではありませんが、優先順位表には必ず載っているべきです。
美しいコードとは何でしょう。Rubyでは、Ruby独自のイディオムとカスタムなドメイン特化言語(DSL)の力が合わさった場合によく見かけます。それはあいまいですが、やってみる価値は十分あります。
以下に、Active Recordからの簡単な例を示します。
class Project < ApplicationRecord
belongs_to :account
has_many :participants, class_name: ‘Person’
validates_presence_of :name
end
これは、DSLのように見えますが、シンボルとオプションを取る3つのクラスメソッドを呼び出す単なるクラス定義です。ここには、奇抜な所は何もありません。しかし、確かにきれいです。確かにシンプルです。このいくつかの宣言から計り知れない力と柔軟性を感じます。
美しさの一部は、これらの呼び出しが、前述の「設定より規約」のような原則を守っていることに起因しています。belongs_to :accountを呼び出すとき、私たちは、外部キーの名前がaccount_idであり、それがprojectsテーブルにあると仮定しています。また、participantsに関連付けされるclass_nameにPersonを指定する必要がある場合でも、そのクラス名の定義さえあればいいのです。そこから、外部キー及びその他の設定ポイントが再び導き出されます。
次に、データベースのマイグレーションシステムから別の例を示します。
class CreateAccounts < ActiveRecord::Migration
def change
create_table :accounts do |t|
t.integer :queenbee_id
t.timestamps
end
end
end
これが、フレームワークの真骨頂です。プログラマは、一定の規則に従って、#changeを実装しているActiveRecord::Migrationのサブクラスとなるようにクラスを宣言します。そうすると、フレームワークは、それをひと通り全部調べて、これが呼び出すメソッドだと認識します。
このとおり、プログラマは、ほとんどコードを書く必要がありません。マイグレーションの場合には、Railsのdb:migrateを呼び出して、この新しいテーブルを追加してデータベースをアップグレードすることもできますし、反対に、別の呼び出しでこのテーブルを削除することもできます。プログラマがこれを全て実現させ、自分自身で呼び出すライブラリからワークフローをまとめ上げるのとは、随分違います。
しかし、美しいコードは、あまり目立たないときもあります。できるだけ短くて強力なコードにするより、宣言のフローを繰り返すのです。
次の2つのステートメントは同じ操作を行います。
if people.include? person
…
if person.in? people
しかし、フローとフォーカスが微妙に異なっています。最初のステートメントでは、フォーカスが当たっているのはコレクションで、それが対象です。2番目のステートメントでは、対象は明らかにpersonです。2つのステートメントの長さはそれほど変わりませんが、personに関する条件式の場合は、私は、2番目の方がはるかに美しく、ほほ笑みたくなると強く主張します。
統合システムを尊重する
Railsはいろいろな状況で使うことができますが、一番気に入っているのは、統合システムを作ることです。壮大なモノリス。問題全体に対処する完全なシステム。これは、Railsが、ライブアップデートを行うために必要なフロントエンドJavaScriptから、稼働環境でデータベースをあるバージョンから別のバージョンに移行する方法まで、全てに関わっていることを意味します。
今まで議論してきたように、これは非常に範囲が広いですが、1人の人間が理解しきれないほど広くはありません。具体的に言うと、Railsは、個人のジェネラリストが、こういう完全なシステムを作れるようにしようと努めています。その目的は、スペシャリストを小さなニッチに隔離し、「永続的な価値のあるものを構築するためには、前述のようなジェネラリストだけからなるチームが必要だ」とすることではありません。
統合システムに目を向けるのは、個人に能力を与えることに重点を置いているからです。統合システムでは、多くの無駄な抽象化を省き、(サーバとクライアントの両方にあるテンプレートのように)層の間の重複を減らし、何よりもまず、完全に確信が持てるまでシステムを分散させないようにすることができるのです。
システム開発における複雑化の多くは、「要素間に新しい境界を導入することによって、AとBの間で通信を行う方法が制限される」といったことに起因します。オブジェクト間のメソッド呼び出しは、マイクロサービス間のリモートプロシージャコールよりも、はるかに簡単です。マイクロサービス間のリモートプロシージャコールは、障害状態、待ち時間の問題、あえて分散の泥沼に入ろうとする者を待ち受ける依存関係の更新スケジュール……などとという、全く新しい苦痛に満ちた世界です。
時には、この分散も必要です。他の人がHTTP経由であなたのWebアプリケーションを呼び出すことができるAPIを作成したいのなら、それらの問題に対処しながら、がんばってやるしかありません(インバウンド要求を処理するほうが、アウトバウンド要求を送信するよりもずっと簡単ではありますが、あなたのシステムの停止時間が、誰か他の人の障害状態になるということです)。しかし、それは、少なくともあなた自身の個人的な開発経験に限られたダメージです。
さらに悪いのは、システムをサービスに分解するのが早すぎる場合です。マイクロサービスの場合は、もっと大変です。この原動力は、しばしば、最新のインターネットアプリケーションがほしい場合には、ひたすら何度も繰り返しシステムを構築する必要があるという誤解から始まっています。サーバ側で一度、JavaScriptMVCのクライアント側で一度、各ネイティブモバイルアプリケーションで一度ずつ、などなど。これは、自然の摂理ではありません。そうする必要はないのです。
複数のアプリケーションとアクセスの間で、アプリケーション全体の大部分を共有することは完全に可能です。ネイティブモバイルアプリケーションに埋め込まれたのと同じコントローラとビューをデスクトップのWeb用に使用することも可能です。華麗で壮大なモノリス、つまり統合システムの中では、できる限り一元化することも可能なのです。
それどころか、速度も、ユーザエクスペリエンスも、またはその他の属性(開発者に不当に早すぎる分散をさせようとするようなもの)も、あきらめる必要はありません。
私たちが求めているものをほぼ全て兼ね備えたもの。つまり、それが、1つの統合システムとしての使いやすさと分かりやすさを備え、個別にチューニングされ分散されたアプリケーションの力なのです。
安定性より進歩を重視する
Railsのように10年以上も活用されているシステムは、自然と固定化していく傾向にあります。以前の振る舞いを頼りにしていた人、頼りにしていた場では、どんな変更でも問題になる可能性があるのは当然です。その理由も、各自にとってはもっともなものです。
とはいえ、保守的な意見に耳を傾け過ぎていると、逆の立場が見えなくなってしまいます。進化と発展のためには、時には思い切って慣習を破り、変化を取り入れる必要があります。その進化があってこそ、Railsはこれまでの(そしてこれからの?)10年も存続し普及してくることができたのです。
これは理屈として理解するのは非常に簡単ですが、実際問題として受け入れるのはかなり難しいことです。特に、Railsのメジャーバージョンで後方互換性のない変更があったために、自分のアプリケーションが使えなくなった場合はなおさらです。そのような時には、安定性より進歩を重視するという価値を思い出す必要があります。欠陥をデバッグして解決し、時代と共に前進する勇気を持つためです。
いやおうなしに不必要な打撃や過度の打撃を負わせても仕方ない、という意味ではありません。Rails 2.xからRails 3への大移行に携わった人は、その時の傷痕がいまだに消えずにいます。大変な作業でした。2.xの世界に長い間多くの人を置き去りにした大変革で、納得以上に失望を感じた人もいました。ですが大局的に見れば、やはり価値のあることでした。
これは、私たちが続けていかなくてはならない厳しい取引です。今日行う変更の結果、Railsは5年後、より発展しているでしょうか? 今後、ジョブキューイングやWebSocketといった別の問題領域に取り組めば、Railsはもっと普及するでしょうか? もし答えがイエスなら、早速真剣に取り掛かりましょう。
上記の作業はRails自体だけでなく、さらに大きなRubyのコミュニティにも発生するものです。Railsは、構成要素にRubyの新しいバージョンを素早く採用することで、Rubyの発展のために先頭を切って貢献するべきです。
この点について、今まで私たちは非常によく対応してきました。私が始めた時以来、Rubyの方は1.6、1.8、1.9、2.0、2.1、2.2を経て、現在はRuby 2.3となっています。その間、大きな変更はたくさんありましたが、RailsはRubyの後ろ盾のもとに存在し、人々がプログラムをより早く理解するのに役立っています。それは、Rubyの主な普及役を務めてきたRailsの特権と責務の一部です。
このことは、関連する補助的ツールにも当てはまります。Bundlerの概念はかつて物議をかもしましたが、Bundlerは共通の未来にとって不可欠なものであるとRailsが主張したことで、今では当然のツールとなっています。同じことはアセットパイプラインや、永続的なコマンドプロセスを提供するSpringにも当てはまります。これら3つでは全て、過去あるいは現在でも苦労の増加を経験していますが、長期的に見て価値のあることは明らかだったからこそ、続けてくることができました。
進歩とは結局、変化を推し進めようとする人とその意志によるところが大部分です。そのため、Rails CoreやRails Committersなどに無期限のメンバーはおらず、どちらもフレームワークを向上させるために積極的に活動している人たちのためのグループとなっています。中には数年間だけ携わるメンバーもいるでしょうが、私たちはそのような人のサービスもずっと歓迎していきますし、一方では、何十年にわたり継続する人もいるかもしれません。
また、コミュニティの新メンバーを歓迎し促すことが大変重要な理由も、そこにあります。進歩をより良いものにするためには、新しい風と新しいアイデアが必要なのです。
テントを押し上げる
Railsには異論のあるアイデアがたくさん取り入れられているので、もしあらゆる考え方に対して完全に従うよう常に皆さんに求めていたら、Railsは思想的な隠者が集まるグループとしてすぐに孤立してしまうでしょう。ですので、それはありません!
私たちには、意見の違いが必要です。方言が必要です。多様な思考、多様な人々が必要です。このアイデアのるつぼこそ、誰もが共有できる最良の場所となるでしょう。コードや進行中の議論に対して、たくさんの人が自分の意見を出せるような場です。
そんなわけで、この基本原則は理想形を示していますが、日々の現実はもっとニュアンス豊か(で興味深いもの)になっています。Railsが1つのテントの下にこれほど大きなコミュニティを抱えることができるのもまさに、リトマス試験の類がたとえあったとしても非常に少ないからです。
テスト用のDSLであるRSpecに対して私は何度も大きな不満を表明しているのですが、このRSpecが成功を続けていることが何よりの証拠です。私は自分がRSpecに反対する理由についてとことん主張でき、一方でRSpecは今もなお成功し発展することができます。その事実の方がずっと重要なのです。
同じことは、RailsがAPIとして使われるようになったことにも当てはまります。私が個人的に注目し力を入れているのはビューを含む統合システムですが、クライアントとサーバを前もって分散したいと考える人にとってRailsが役立つ余地も間違いなくあります。この点については、副次的な用途として共存できる限りは受け入れるべきで、それはきっと可能だと思っています。
ただし、大きなテントを張るというのは、みんなに気に入られようとすることではありません。パーティーに来る人は誰でも歓迎し、飲み物も持参OKにするというだけなのです。他の人たちの参加を促すからといって、私たちの精神や価値観は何一つ損なわれてはいけませんが、今まではなかったおいしい飲み物をちょっと加える方法が学べる可能性は十分あります。
これは代償なしに実現できることではありません。歓迎的な環境を保つ努力が必要です。特に、コミュニティの既存メンバーと同じような人をさらに集めることだけが目的でない場合は、なおさらです。敷居を低くすることは、私たちが常に真剣に考えるべき仕事です。
隣で単にドキュメントのミススペリングの校正を始めようとしている人が、いつ次の素晴らしい機能を実装することになるかは分かりません。ですが、どんなささやかな貢献に対しても喜んで感謝を伝えていくことで、モチベーションにつながり、その瞬間に立ち会えるチャンスが得られるようになるのです。
株式会社リクルート プロダクト統括本部 プロダクト開発統括室 グループマネジャー 株式会社ニジボックス デベロップメント室 室長 Node.js 日本ユーザーグループ代表
- Twitter: @yosuke_furukawa
- Github: yosuke-furukawa