エンジニアHubproduced by エン

若手Webエンジニアのための情報メディア

直面する問題を解決したらkaminariができた。Ruby / Railsコミッター松田明のOSS開発の実像

世界中のRubyプログラマに使用されるOSSであるkaminari。これを手がけたRuby / Railsコミッター松田明さんに、開発背景を聞きました。

「これがあったら便利なはずだ」という予測。
あるいは、「これが問題だから、解決する」という現状認識。
新たな技術が生み出される源流にあるものとは、一体なんでしょうか。

Ruby on Rails(以下、Rails)を用いたWebアプリケーション開発において、圧倒的な存在感を放つページネータであるkaminariを開発した松田明(まつだ・あきら/ @a_matsudaさんの場合は、“絶対に”後者であると語ります。

Rails、そしてRubyのコミッターでもある松田さんは、まさにRubyを用いた開発の最中、先行するソフトウェアに感じた課題を解決するべくkaminariの開発を手がけ、いまや、同ソフトウェアはGitHub上で7,000を超えるスター数を獲得しています。

自身の感じる課題に向き合うことが開発のモチベーション、と語る松田さんにとって、「OSSへのコントリビュート」とはどのような意味を持つのでしょうか。また、RubyKaigiやAsakusa.rbといったコミュニティ活動の運営に傾倒する背景を聞きました。

自然言語を得意とするエンジニア

──まずは松田さんのキャリアについてお聞かせいただいてよろしいでしょうか?

松田 今は、特定の企業に所属しているわけではなく、フリーランスとしていくつかの会社から同時にお仕事をいただいています。技術顧問、いわばアドバイザーのような仕事が多く、今だと9社ほどと関わっています。

──9社!? そんなに多くの企業と関わっていたのですね。

松田 そうなんですよ。平日の5日をどう使うかの時間のやりくりは大変ですね(笑)。会社員としてやっていたのは、社会人になった最初の1年くらいで、2003年にフリーランスとして独立したので、15年ぐらいは一人でやっていることになります。

フリーランスになってから、最初は受託開発などをやることが多く、当時はVBやJavaや.netを使っていました。その後Railsと出会い、Railsはもう13年くらい使っていますね。

その過程でRuby / Railsを使っていてバグを踏んでしまった部分とかを、自分で修正したり、作者に指摘したりしているうちに、仕事をしつつOSSプログラマーとしていろいろとプロダクトをリリースするようになっていったんです。

松田明さん:日本人として唯一、RubyおよびRuby on Rails双方のコミッターを務める。また、kaminari、active_decoratorなど数多くのOSSを手がけるかたわら、Asakusa.rbやRubyKaigiといったRubyに関するコミュニティ活動の運営にも従事する。現在はフリーランスのエンジニアとして、複数の企業の技術顧問活動を行う。

──キャリアを重ねていくなかで、ご自身の技術的な強みはどの部分にあるとお考えでしょうか?

松田 難しい質問ですね(笑)。おそらく「RubyやRailsに詳しい人」ということで自分を買っていただいているのかなと思います。

Ruby / Rails双方のコミッターをやっているので「どちらも日本国内では何番目かに詳しいです」というのが商品価値としてあると思っています。世界でも両方のコミット権限を持っているのは僕とAaron Pattersonだけです。

Aaron Patterson:RailsやRuby、sqlite3などのコアな部分に多くコミットしている。またRubyのHTML,XMLパーサーライブラリであるNokogiriの作者でもある。

──どのようなモチベーションが精力的な活動を支えているのでしょうか。

松田 僕は抽象的な問題を解くのが好きなんです。パズルとか詰将棋を解く感覚ですね。

たとえば受託の仕事だと目の前のお客さんが抱える具体的な問題があって、それをコードで解決してお金をいただくのが一般的ですよね。僕はこうした仕事のキャリアは長いのである程度うまくやれると思っています。ただ、問題解決のプロセスがスケールしなくて、なかなか大きな手応えが得られないんですよね。

一方でアルゴリズムとか計算量とか、コンピュータ・サイエンスに関わるレイヤーのプログラミングもありますが、そういうのは自分にとって実は気持ちが入らない。あまり得意だと思っていないし、自分よりもっと専門性の高い人はたくさんいると感じます。

自分の得意分野はその両者の間くらいにあると思っていて、「言葉を扱う能力」の領域というか……。言葉を使って物事を整理して考え、それを表現して伝えること。こうした領域が自分が好きで得意なところだと思っています。

もっとも、プログラミングの作業とはそもそもこういうものだと思うんです。自然言語ではなくて、プログラミング言語を使って問題を整理して、筋道を立ててコンピュータに解決させる作業だと思っています。なので自然言語の技術はプログラミング技術にも影響していると感じます。

──プログラムのコードと自然言語はある程度イコールの関係であると言えるということでしょうか?

松田 そう思う部分もありますね。Rubyが面白いのもそこだと思っていて、すごく自然言語に近い形でプログラミングできます。喋ってるような感覚で作れるのが好きですね。

will_paginateが動かない。だからkaminariを作った

ページネーションのライブラリであるwill_paginate。kaminariのルーツと呼ぶべきOSSだ。なお、作者は後にGitHubを作り出すこととなる。

──さて、松田さんが送り出したkaminariは今やRailsでWebアプリを作る際に、必ずと言っていいほど使用されるページネータだと思います。そもそもどうして作ろうと思ったのでしょうか?

松田 Rails 2.0のときはページネーションのライブラリにはwill_paginateを使用していたんですけど、3.0では動かなくなってしまったんです。

Rails 2.0の頃から僕はRailsの開発に関わり始めていたんです。3.0へのバージョンアップは開発に2年くらいかかっていて、ビックバンリライティングと言われるくらい大きなバージョンアップだったんですね。

僕はこの3.0が大好きで、3.0をリリースした頃に自分が手がけていた小さいプロジェクトにwill_paginateを適用したら動かなかったんです。仕方がないから必要な機能を3.0に合わせて自分で作ったページネータがkaminariです。

──kaminariを作る際にwill_paginateを参考にして作った部分などはあるのでしょうか?

松田 ありませんね。自分でゼロから作りました。なぜかと言うとwill_paginateのコードは書き直したいところだらけだったからです(笑)。プルリクエストを送る方法もあったと思いますが、根本から書き直した方が早いと思ったのです。

OSSのライブラリが動かなくなった時に修正する方法は、いくつかあると思います。一番簡単なのはプルリクエストでパッチを投げて修正して動かす方法。もう一つはフォークして手元で改造して使う方法。さらに、自分で作る、という方法があると思います。kaminariは3つ目を選択したということです。

──kaminariの開発で工夫したところや、will_paginateから改善しようと思った点はありますか?

松田 一つはkaminariはDSL(Domain Specific Language)的な書き方ができる、というアイデアです。それから実装面では、kaminariはRails Engineとして実装した点が挙げられます。Rails Engineは、Railsに小さいアプリケーションを入れられるというもので、内部にMVCがあり本体を拡張するようにレイアウトして使えます。

will_paginateが動かないという問題を見た時、その解決にRails Engineが使えそうだというイメージがあり実装してみたんです。

──ではRails Engineがなければ、kaminariは生まれなかった可能性があるということでしょうか?

松田 そうですね。Rails Engineというインスピレーションがなければ生まれてなかったかもしれません。

参考:Getting Started with Engines

──ちなみになのですがkaminari自体は「誰かのために作った」という気持ちはあったのでしょうか?

松田 それは全くないです。自分が直面していない問題には気持ちが入らないので(笑)。

よく「フルタイムのRuby / Railsのコミッターはやらないのですか?」と聞かれますが、自分が直面していない問題を想像力で探すっていうのは僕にあまり向いてないんですよね。

──では、松田さんの「何か作りたい」という欲求のモチベーションは何でしょうか? Rails Engineのように新しいものを使ってみたい、というモチベーションなのでしょうか。それとも、なんらかの問題を解決したいというモチベーションなのでしょうか?

松田 それは絶対に「問題ありき」だと思います。例えばRailsというフレームワークにしても、「フレームワークを作ること」を目的として作られたわけではないですよね。もともとBasecampというプロジェクト管理アプリケーションがあり、そこからスピンアウトして、要求に応じて作り出されたのがRailsです。Railsの新機能も全部そうで、実際に現場で使用されているものをフレームワークにどんどん加えていると思います。

プラグインなどのソフトウェアも、自分が直面する問題を解決するべく生み出されるのが自然なスタンスだと思っています。自分が使わないのに「きっと誰かが欲しがるだろう」という意思で作ることはありません。

自分が携わっているアプリケーションでコードを書いて不満や不具合が出てきて、それを解決するためのツールをちょっと作ってみる。そして、ある程度の汎用的なものがパッケージできたら、それを発表してみる、というのが僕にとって自然な形です。

kaminariの運用は失敗だらけだった

kaminari1.0.0 beta1のリリースノートでは、Rails 4.0やRuby 1.9のサポート終了、SinatraやMongoidの別gem化、slim/hamlのコマンドの非推奨などが発表された。

──kaminariを開発されてから6年ほど経って、去年バージョンがついに1.0になりました。機能が分離されていたり、非推奨になったものが発表されたり、内部の設計がかなり変わっていて驚きました。ここまで大きく変更したのには何か理由があるのでしょうか?

松田 kaminariに関しては、デザインや運用、育て方など失敗した部分がいっぱいありまして(笑)。

フレームワーク・アグノスティックな何でもページネーションできる万能プラグインにしてしまったんですね。フレームワークがRails以外、例えばSinatraでも使えたし、 テンプレートもERBでもHamlでもSlimでも使える。O/RマッパーはActive RecordでもMongoidでも使えるんです。

それを1つのパッケージにまとめちゃったのが大失敗で、世界中からいろいろなプルリクエストが送られてきますが、自分が使ってないO/Rマッパーやフレームワークに対応した、というものが大量に送られてきて……。

僕では判断もメンテナンスもできないというのがすごい足かせになってしまい、1.0以前の状態はゴテゴテのぐちゃぐちゃになっていました。モンキーパッチの寄せ集めみたいになっていて、すごく見苦しいコードベースになってしまったんです。

次はそういう状態に陥らないように、と思えたので良い経験にはなりましたが(笑)。

──汎用的であることはライブラリとして悪くない要素でもあると思うのですが。

松田 自分がRailsをメインで使っていてActive Recordが大好きなので、それ以外のフレームワークやO/Rマッパーをあまり使わないんですよ。汎用的すぎたというか、「自分の問題を解決するためのプラグイン」という観点からはkaminariは外れてしまっていたんです。

Mongoidへの対応などを別のgemに分けたのは、その機能が自分にとってコアの外側にあると感じたからです。ただ、それだけじゃなくてTravis CIのリソースがとんでもないことになっていたというのもあります。複数のバージョンのRubyと、複数のバージョンのRails、O/RマッパーがActive RecordとMongoid……、という具合にテストをしていて、掛け算すると100パターン以上も回すことになっていたんです。Travis CIは無料で使わせてもらっているのにリソースの無駄ですよね。地球に優しくない(笑)。

それでそこをもっと軽くしたいというのと、Mongoidの問題を修正したプルリクエストはそもそもMongoidのビルドを通せばいい、というだけの話です。そういった経緯もあってgemを分けたのです。

──「自分では興味を持てず対応できないプルリクエストが送られてくる」とおっしゃっていましたが、やはりOSSは作者自身が全てコントロールできるのが理想なのでしょうか?

松田 そうですね。僕にとってはOSSは基本的に個人活動でしかなく、モチベーションを感じないと手が動かない。kaminariは僕が興味のないものとか、よく分からない要素が増えすぎちゃったんです。issueやプルリクエストも放置してしまって、100件以上もissueが溜まっていて、どうしていいのか分からないという状況もありました。

ただkaminariに関してはメンバーに恵まれていて、西嶋悠貴さん( @yuki24)という共同メンテナーがいて彼が幅広く見てくれています。何年も前からずっと支えてくれていました。

kaminariは僕の個人アカウントの下にあったんですけど、1.0を出すタイミングでチームのものということでオーガニゼーションを作りました。まあ、実質僕と西嶋さんの2人だけのチームですが(笑)。

──kaminariのリリース後でエンジニアとして何か変わったことや反響はありましたか?

松田 名刺が1枚できたというのあります。海外のカンファレンスなんかではプロダクトこそが名刺になるという部分があります。自分がkaminariの作者だというと、認識してもらえるのは意味があります。

もっとも、自分の場合は「kaminariの作者」というより、Railsコミッターとしての立場の方がプレゼンスがある気がしますね。海外でもkaminariはたくさん使われていますが、僕が作者だと分かると苦情を言われることが多い(笑)。「名前の意味が分からない」「つづりが覚えられない」「発音できない」など、いろいろ言われます(笑)。

──kaminariという名称に由来はあるのでしょうか?

松田 本当は普通の名前、『page_◯◯』みたいな名前をつけようとか考えていたんです。Ruby GemsってTwitterのアカウント名のように早いもの勝ちで命名できるんです。なので、それっぽい名前のgemがすでにいっぱいあったんですよ。

だからプロダクトはできているのに、名前がないからリリースできないという状況が数週間も続きました。そのときにAsakusa.rbメンバーの柴田博志( @hsbt)さんにkaminariという名前をつけてもらったという経緯があります。RubyにはNokogiri(ノコギリ)というスクレイピングのgemがあって、それへのリスペクトのような感じです。ただ、kaminariの命名はよくないプラクティスですね。特に海外からは不評なのでマネしないほうがいい(笑)。

自分が作っているものは全て知りたい。血の通ったコードの意味

──松田さんはコミュニティ活動にも精力的に取り組まれています。これはなぜでしょうか?

松田 Rubyコミュニティは伝統的に飛び込んでくる人を大事にしようっていう文化があると感じています。Asakusa.rbも当時は何者でもない僕が「Ruby大好きです! 何かやってみたいです!」っていうところから始まって、やっぱり周りの人たちが支えがあってここまでやってきた。そして、先達から「次は君の番だ」という風にバトンを渡されたという部分があります。

もう一つ、OSSを開発するのと同じ理由かもしれませんが、自分がやりたいから、という理由ももちろんあります。RubyKaigiに関しては、自分が最高に楽しめる理想のテックカンファレンスが欲しかったから作ったんです。

RubyKaigiは松田さんが中心となり運営している日本で最大のRubyのカンファレンス。年に一度行われており、2018年は5月31日〜6月2日の3日間にわたって仙台で開催される。

──RubyKaigiを「楽しい」と思える部分はどこなのでしょうか?

松田 「コードを書いた人が登壇している」ということを大事にしています。僕がミーハーなのでコードを書いた本人の言葉が聞きたいんですよね(笑)。

──イベントが「直接コミュニケーションをとる場所」としても機能しているんですね。

松田 僕の場合は、いわゆる勉強会のようなもので勉強することよりも、コードを書いた人に会いに行くことがモチベーションです。作者自体に興味があるんです。だから自分がいいなと思ったプロダクトがあったらその人と友達になりたいし、会いに行きたくなります。

「誰が作ったか知らないし、中身もよく分からないけれどとりあえず動く」というのと、顔を知っている友達が作ったライブラリというのでは、温かみが違うと感じます。コードに血が通う感覚がして好きなんですよね。

Asakusa.rbは松田さんが運営に携わるRuby技術者たちが集まってハックする地域Rubyistコミュニティだ。

──「動けばいい」と思ってしまう人もいると思うのですが、血の通ったコードである必要性はあるのでしょうか?

松田 感情でしかないかもしれませんが、僕はプログラミングがやっぱり好きで、作っているもの自体も好きになりたいんです。そう考えるとやっぱり友達が作ったものを使いたくなるんです。もう一つ、自分がやっているプロダクトのコードはきちんと把握したいんです。コントロールできないと不安になるし、自分が触れる範囲が広くないと気になっちゃうんですよ。

そもそもアプリケーションって、その会社のプライベートリポジトリにコミットしているものだけじゃなくて、そこで使っているプラグインやフレームワークや言語も全部含めてアプリケーションが成立しています。ですから、理想を言うと自分が使っているライブラリなどのソースコードは全部読んだ方がいい。

Rubyのアプリケーションの場合、フレームワークやライブラリもほとんどがRubyで書かれています。つまり、フレームワークとライブラリの境界が希薄で、全部自分のテリトリーなんですよ。アプリにライブラリをバンドルした瞬間に、自分にもそのライブラリのメンテナーとしての責務が発生すると思って開発するのは大切なことです。

コミットログにソフトウェアの哲学を見る

──RubyやRailsに関わり、OSSも自ら開発していると相当な数のプルリクエストを目にすると思いますが、松田さんが考える良いプルリクエストとはどんなものでしょうか?

松田 教科書的ですが、ユースケースがちゃんと書けていることは大事ですね。

  • 自分のプロジェクトで〇〇な結果を期待して使った
  • だけど、実際には△△になってしまっていた

こんな風にストーリーに納得できると、気持ちよく緑のmergeボタンが押せますね。

逆に悩ましいプルリクエストは「〇〇 should be △△」みたいな「〇〇じゃないのはおかしい。だから直したい」という場合です。本当におかしい場合もあるんですけど、やっぱりリアルなシナリオに則している方が、作者としても「なるほど」となりますよね。

──OSSのユーザーとしてはいかがですか?

松田 ユーザーというか読者として僕が大事にしているのは、プルリクエストよりコミットなんです。ソフトウェアはコミットの積み重ねですから、ある時点だけ切り取ったソースコードを読んでもあまり伝わらないと思っていて、ソフトウェアの歴史や、作者の思想はコミットに込められているように思います。

だから、僕がコードリーディングする時はmasterをチェックアウトして読むのではなく、コミットを最初から通読しています。良いコミットが積まれているプロダクトは読んでいて気持ちがいいので、気に入ったものは最初から読んでしまうんです。

──松田さんはkaminariだけでなく、Rails / Rubyにコミッターとして関わっています。コミッターとしての活動に使命感のようなものは感じているのでしょうか?

松田 それはないですね。実は、僕はcontribute(貢献)という言い方がすごく嫌いで、違和感を感じているんです。

時に「自分もOSSのコミッターになりたいんですけど、どこから始めればいいですか?」と聞かれることがありますが、コミットが目的になってしまうなら、僕は「やらなくていいんじゃないの?」って思ってしまうんです。

自分が日頃やっているプログラミングの延長にコミットがあり、結果としてコミッターになるのが自然な流れだと思うんですよね。アプリケーションを書いてるうちにバグを踏むことがあるでしょう。それを自分でパッチを当てて直していき、その結果がcontributeになるだけなんです。だから僕はハックをするためや、他人に貢献することを目的ににOSSをいじるということはしません。

人が生み出すソフトウェア。だから人を知る

──RubyやRails、そしてkaminariなどのOSS開発は、松田さんにどのような影響を与えましたか?

松田 さまざまなソフトウェアにコミットをしてきて、それを見てくれている方に評価してもらい、結果として今につながっているのかなと思います。先ほども言ったように、OSS活動は個人の趣味のようなものです。しかし、趣味を貫いたら食いぶちになっていたというのは面白いですよね。

OSSのおかげで複数の現場で技術顧問などをやっていますが、どの会社も同じバグを踏むことがあり、みんなそれぞれ同じような直し方で対処しています。つまり、A社のビジネスのコアバリューに触れない部分のバグ修正であれば、その情報をB社に共有できる。異なる会社が抱える共通の問題を、僕を仲介とすることで、解決を省略できると思うんです。

そういったことができるのは、やはりプロプライエタリ製品ではなくOSSを利用しているからこそであって、そこをもっと踏み込んでお手伝いしている感じですね。

──今の20代ぐらいの若い人たちはどうやってOSSに関わっていけばいいでしょうか?

松田 OSSをやってる人たちはどこか抜きん出ている人が多い印象です。本当はやらなくてもいいアウトプットをしているくらいなので、ユニークな主張を持っている人たちなんです。

人間的な魅力が溢れ出してしまい、それがコミットにつながっている人が多いのか、人を見ているだけでも飽きないんですよ。OSSというのは、それを作っている「人」があってこそ産まれているんです。

ですからRubyKaigiのようなカンファレンスやコミュニティに参加して「人」を見てほしいですね。どういう人が何を考え、どんなコードを書いて、何を作っているのかを見ると、OSSがもっと身近に感じられるようになるはずです。

──まずはコミュニティ活動の場に行って、コミュニケーションをとるのが大事ということですね。

松田 そうですね。足を運んでコミュニケーションをとるのが、OSSの世界に入っていく入口としてはすごくいいと思います。

関連記事

取材:megaya megayaのブログ