そのうち30人弱が日本人。アメリカを除くとドイツに数人いたかな。40人いるといっても2、3回コミット(オリジナルのソースコードの変更)をして、それきり見かけないという人もいます。ライブラリをコミットするためにコミッターになって、そのライブラリが安定したらもうコミットしないという人とかね。いう意味ではRuby全体を見ているコミッターは5〜6人でしょうか。Rubyの場合、私のところ(NaCl)を除くと、少なくとも企業を看板にしている人はいませんね。——40人のコミッターは平等な立場ではないのですよね。明らかなバグの修正であれば、みんな勝手にコミットしますけど、仕様に関わるようなところは、まつもとさんにお伺いを立ててからということになっています。1.9について教えてください。1.9.0正式版がリリースされた)。——実際は動いているコードがあるので、いまでも出せるといえば出せますよね。いや、ちょっといまのままでは出せませんね。バグ報告をいただいているのが収まっていないので......。バグはしょうがないよ。どこまで互換性を考えるかですけどね。Rubyから見たら内部インターフェイスは変わらないかもしれないけど、まだC言語レベルで変わる可能性が残っていて......。1.8だとまずいけどさ。1.8の立ち位置ってRailsが出てきてだいぶ変わりましたよね。以前は良くも悪くも、まつもとさん個人のプロジェクトという側面が大きかったじゃないですか。それがいまや「安定しなければならない」という周囲からのプレッシャーのようなものがありますよね。1.8に関してバイナリ互換性がなくなったらまずいと思うんだけど、1.9はいいんじゃないかな、という判断です。少なくとも1.8と1.9の開発が並行して動いている間は。1.8は安定してきていますよね。いまはリリースマネージャも2人いるし。——安定性を求めるなら1.9の新しい仕様は使わず、安定版の1.8を使ってくださいということですね。Railsも1.9対応になっていないですしね。世の中の人は1.9にも1.8との互換性や安定性を求めていますよ。JavaのVMでサン・マイクロシステムズが「次バージョンでバイナリ互換性はなくなります」なんてことを言ったら大ブーイングですよ。——これは原稿にするとまずいのですよね......。いえいえ、逆にこれをちゃんと伝えていただきたいんです。1.9は安定版じゃなくて開発版です。Edge)といって血がどばどば出ている状態のものです。そのために1.8系を用意しているということです。1.9の荒削りな部分が丸くなるには年単位で時間がかかると思うんです。そのときまでは1.8が運用されていると思います。何かの事情で1.9をエンタープライズで使いたいということであれば、自己責任でやっていただくしかない。1.9とかい離していく可能性もあるんじゃないですか。2.0が1.x系をサポートするJRubyと別物になる可能性はありますよね。JBossのバックにはレッドハットがいて、サポートがあります。Rubyにそれがあるかというと、ありません。まつもとさんの所属するNaCl(ネットワーク応用通信研究所)は、Ruby関連のサポートを提供しているとはいえ、基本的にはまつもとさんを雇っていること以外のコミットメントは、あまりしていませんよね。いう意味で、ほかのエンタープライズアプリケーションとは違います。エンタープライズ向けの開発・サポートを期待する方々がいるのは分かっていますけど、RubyをJBossのようなものと同じ土俵で考えると違います。Rubyでも、そういう体制ができればいいのかもしれませんけどね。いう受け皿としてRubyアソシエーションを考えてはいますけど、いまのところ1人雇ったら予算が全部吹っ飛んじゃうので、まだ難しいですね。そのために法人格を取ったんだしね。法人格が必要なことは、予算の範囲内で何でもやりますよ。Rubyに対する投資や寄付についても、準備が整ったら始めたいですね。誰もが名前を知っていてグローバルに事業を展開している企業からもアプローチがあったりするんですよ。企業ユーザーにしてみれば、1.8がより安定することもうれしいでしょうし、1.9がより早くエンタープライズレベルに到達することもうれしいでしょうから、どっちに投資していただけるかは企業次第でしょうね。1.8基金とか1.9基金と分けて寄付に紐を付けるのかどうかは、まだ決まってません。できれば使い道はRubyアソシエーションに一任して欲しいですけどね。理事長としての私のアイデアの段階ですけど、Ruby関連の開発プロジェクトを公募して、少額の助成金を出す「マイクログラント」を考えています。Railsでも、ともかくRubyに関連したことであれば対象にします。数十万円という額ですけど、それでもプロジェクトをやりたいという人がいるようであれば、お金を出したいですね。人数的に厳しいかもしれませんけど、選ばれたプロジェクトのメンバーには、導き手となるメンターも付けられればとも考えています。私、メンターやりたいです。1.9と1.8の違いについて教えてください。最大の違いは笹田くんが書いたコードが入っていることです。1.8は、ぼくがこつこつ作ってきたものの延長で、非常に素朴な実装になっています。Tree)というものを構成して、そのツリー構造をたどりながら処理を実行しています。この処理を担当する「eval.c」という1万数千行のコードを全部取っ払って、1.9では笹田君が書いた「YARV」という仮想マシン(VM)のコードを入れました。クルマにたとえれば、エンジンが入れ替わったようなイメージでしょうか。重量比的には大きな割合ではないけど、決定的な違いです。ランタイムやライブラリはそのままです。1.9でも、先ほど言ったASTは作るんですけど、それをバイトコード——実際にはワードコードですけど——という数字の列に変換して、それを実行する形になります。要するに1段階、ステップが増えています。JavaのVMと同じで、あの構造に追い付いたということです。ありますが、起動時に100分の何秒か遅くなるという程度です。普通のプログラムであれば、読み込んで1回だけコンパイルしてASTを作り、1回だけバイトコードに変換して実行するので影響は小さいんです。プログラムが10万行もあればコンパイルに時間がかかると思うんですが、Rubyでそこまで大規模なものは、あまりないですよね。RailsをCGIで使うとなると、ちょっと問題になるかなという気はしているんですけど......。その辺はプリコンパイルみたいな処理を考えています。ええ、今年の12月に出すバージョンには入れていませんが、そういうことを考えています。道具立てはそろっていますから、やればできるんですけどね。バイトコードを出したいという人は結構いるんですけど、どのぐらい意味のあることなのか、個人的にはちょっと分かりません。少なくともわれわれの興味ではないです。VM化によるメリット——なるほど。これまでできなかった高速化や最適化ができることです。ASTのツリー構造をたどるのは、意外に重たい処理だったんです。ポインタを動かして次のオブジェクトを取り出す、という処理です。このポインタの操作は軽いと思っていたんですけど、結構重たくて......。いまのプロセッサアーキテクチャだと、アドレスが離れてるとキャッシュに当たらないんですよね。それでポインタを動かすとキャッシュミスが起こって、メモリアクセスに余計にサイクルかかっちゃう。VMではバイトコードを順に読み出して実行するので、次の命令を実行するのは配列を1つインクリメントするだけとシンプルなんですよ。VM化によって、いままでできなかった最適化ができるようになります。ASTの場合、この木とこの木を入れ替える、ということが難しかったんですけど、バイトコードのようにシリアルに並んでいる配列をちょこちょこいじるというのは結構簡単にできるんです。例外処理の方法も1.9では変更して速くなっています。1.9ではバイトコードにコンパイルする時に例外処理の飛び先アドレスを書いた表を用意しておくんですね。1.8では、そこをダイナミックにやっていたので余計な処理が発生していた。1.9では例外が発生した時点で初めて処理を行います。これは1.8に比べると少し重たい処理なんですけど、例外処理が発生するのは文字通り例外的なので、例外が起こったときにだけ処理しましょうという発想です。これはVM化によって可能になったことの一例です。これもJavaと同じようにしたということですけど。バイトコードをいかに速く動かすかというのは、長らく研究されていて論文の蓄積もあります。いうアイデアを実装して入れていくことで、だいぶ速くなりました。VMの場合は、ものすごい最適化をしているんですね。x86のこのプロセッサでは、こんなことができる、というレベルで最適化をしています。ものすごく速いですよね。YARVでは、まだハードウェア依存の最適化は手を出してないんだよね。ええ、私1人だけで開発していたので、x86で最適化するとほかのアーキテクチャのマシンで動かないとか、ほかのマシンで遅いままになってしまいます。それが嫌だったので、まずはC言語のレベルでどこまで速くできるかをやってきました。それも、とりあえず一段落したので、次はx86用かなと思っていますけど。JavaだとJITコンパイラとか、Hotspotとか高速化技術がいろいろとありますよね。いうレベルのことです。VM)というオープンソースのソフトウェアがあるんですけど、このLLVM向けに最適化するという手もあります。YARVのバイトコードをLLVM向けにコンパイルすると、ハードウェア依存の部分はLLVMのほうでうまく最適化してくれます。新たに一層加えて最適化を丸投げしちゃうというアイデアです。やってないことはたくさんあります。いや、むしろ時間でしょうか。いま以上に人が集まらないんですよ。私は人が集まればやってほしいなと思っているんですけどね。絶対全部できないじゃないですか。まつもとさんのように全部自分でやりたいというのも理解できますけど。1人じゃ無理ですよね。残念ながら、それは認めましょう(笑)。本当は全部自分でやりたいタイプなんですけど、最近は講演も忙しかったりして......。1999年にはコードネーム「Rite」という名前でRubyもVM化するぞと宣言したんですけど、5年以上ほったらかしにしてあったんですね。そんな自分に対する罰としてVM化の部分は笹田くんに譲りました(笑)うーん、でも、構文木をたどる方式としては、やれることはやってるんですどね。小手先でやれることは限界までやってます。いや、もうちょっとやれると思いますよ。(笑)——ところで、おふたりで仕様や最適化のアイデアについてお話しをされていると、プロ棋士が碁盤なしに頭の中だけで将棋を指している姿を思い出します。ええ、それがいちばん楽しい時間です。さっきも新幹線の中で仕様を考えていました。電車での待ち時間など、暇つぶしの必要がなかったくらい。寝床に入ってしばらくしてから、「はっ、あのバグの原因はあそこにあった!」とひらめくことなんかもあります。最近は、いろいろ手書きでメモを取るようにしていますね。Cで書かれたライブラリが速くなるわけではないので、例えば正規表現を使ってがんがん検索するような処理だとYARVにしても、残念ながら速くなりません。速くなるのはRubyの普通の処理です。変数の代入とかループを回したりという処理が速くなっているので、そこがボトルネックになっているようなものは速くなりますね。パズルとか、文字列処理みたいなものが少ないプログラムは2倍くらい速くなるんじゃないかと思います。——高速になれば適用範囲も広がるんでしょうか。科学技術計算に使えるかといえば、まだそこまで速くないですけど、そのプロトタイピングぐらいには使えるかもしれません。少なくともフィボナッチの結果を見て「Ruby遅い」といっている人たちには、その理由はなくなりましたよと言えるぐらいにはなっています。ああ、それは結構大きい。Shootoutっていうプログラミング言語のベンチマークのサイトがあるんですけど、その成績で言語を決めるという人って結構無視できない数いるんです。ぼくらは「言語の一部の性能しか計測しないマイクロベンチマークなんて意味ないよ」と内心は思ってるんですよ。そんなベンチマークは役に立たないよと言って回るよりは、そのベンチマークで好成績が出るように言語の性能を上げたほうが早い。実際、Shootout系のベンチマークは1.9で速くなるので、Shootoutをマーケティングに逆利用できそうです。私の感覚では普通のプログラムで1.5倍ぐらい速くなるという印象ですね。Rubyは遅いなと感覚的に感じていた方なら、改善される可能性はあります。I/Oやネットワークがボトルネックだと違いますけどね。I/O関連の処理では高速化や最適化でできることがたくさんあるので、これからも速くしていこうと思っていますけど。1.9のベンチマーク結果。D搭載マシンのLinux上で実行した場合。横軸は現行Rubyに対して何倍速いかを示す。フィボナッチ数列の計算では8〜10倍高速化されている。1.9に採用された経緯について、もう少し教えてください。2004年の1月頃に学生で暇だったので趣味で始めました。それから4年経って、やっと実を結んだという感じですね。昔はアドオンみたいな感じだったんですけどね。——ほかにもRuby向けのVMは、いろいろあったし、いまでもあるんですよね。ええ、ほかにもCardinalとかRubiniusとか。YARVが未踏に通ったときには、もう決めてました。最初の未踏が終わった頃には、これはもう物になると思っていました。知らなかった......。私が認識したのは2回目の未踏の成果発表会の日です。発表を盛り上げるために「YARVをRubyに入れていいですか」と聞いたんですね。したら気楽に「うんいいよ」と答えていただいて。YARVのコードを入れてRubyが動いたときは、ちょっと感動しましたよ。前提として、Rubyのポリシーに「内部コードを持たない」というのがあるんですね。内部に特定の文字コードを採用しない、ということです。個々のアプリケーションはそれでいいのですが、プログラミング言語の場合、特定のエンコーディングを選択してしまうと、すべてがそれを選択せざるを得なくなってしまうんです。これは2つの理由で好ましくありません。歴史上、日本には文字コードっていっぱいありますよね、シフトJIS、EUC、JIS、Unicodeと。いう混在環境での処理方法は2つあります。1つは、どれかの文字コードに統一して後で変換して戻す方法です。これだと既存のドキュメントで変換が必須になって無駄ですし、2度の変換で文字化けが発生するという、いわゆるラウンドトリップが出来ないケースが出てきます。ファイルから読んで戻すだけなら同一の変換テーブルを使うのでいいのですが、どこかからデータを読んで書き出すとなると、何が起こるか分からない。考えると、諸悪の根源は変換です。できるだけ変換をやりたくないと、1.8の時代から内部コードを持たないというポリシーでやってきたんです。1つの理由はオープンエンドということです。日本だと、研究者レベルではUnicodeではない文字コードを使っている人もいます。今昔文字鏡やGTコードなどです。したものも平等に扱えるというオープンエンドというのも内部コードを持たないメリットなんです。文字コードは外部の環境の影響も大きくて......。GUIライブラリがUnicodeしか受け付けないとかだと、結局渡す前に変換する必要がありますよね。実はそういうケースが増えていて、ちょっと苦労が報われない感じなんですけど。文字列といったら、ちゃんと文字単位で扱えないと嫌だという声が強かったんですよ。UTF-8だったら、lengthメソッドで返ってくる値はバイト数じゃなくて文字の長さであってほしいと。いうわけで、1.9では文字単位で操作できるようになります。“あいうえお”が5文字です。正規表現を使って文字単位に切って数えます。文字単位で文字列を扱うということは、そもそも正規表現を使うだろうという考え方です。個人的には正規表現でほとんど用は足りると思うんですけど、要望が多かったんです。Rubyの場合、lengthメソッドで文字列の長さが欲しい人もいるし、バイト長が欲しい人もいる。それがなかなか解決できなかったんですよね。Javaの場合、サロゲートペアを使ったUTF-16のエンコーディングで正しい文字数を返すAPIというのが、通常の文字列の長さを返すAPIとは別に用意されています。文字列の長さを返す似たようなAPIが2つあるというのは、シンプルさを重視するRubyとしてはやりたくない。それで、1.9からは文字列1つずつにエンコーディング情報を持たせるようにしたんです。「この文字列はUTF-8で書いてある」というようにです。——Javaに比べてRubyではシンプルさを優先したということでしょうか。私は自分ではJavaは書かないんですが、読んでるだけで頭が混乱することがあります。Rubyでは文字列に文字列を追加することが簡単にできますけど、Javaでは可変長のstringbufferにいったん文字列を入れて、作業が終わったら、そこで確定して固定長のstringに代入するという処理が一般的ですよね。string型とstringbuffer型の2つがあって書き方を覚えなきゃいけない。性能を考えるとそのほうが有利な局面もありますけど、プログラマの書きやすさを考えると、stringという型は1つのほうがいいですよね。1.9の新機能にFiber(ファイバ)が入ると聞きました。Fiber自体はあまり気にしていただかなくて結構です。FiberはGeneratorを実装するために使っています。JavaのイテレータのようなものをRubyで書くのは大変だったんですよね。Javaのイテレータでは、配列からオブジェクトを1つ取ってきて、そのオブジェクトにアクセスすると別の配列からオブジェクトを1つずつ取ってきて順に処理する、ということができるんですね。Rubyではブロックと呼ぶんですが、配列オブジェクト自体がメソッドを持っていて、メソッドの中で閉じているんですね。Javaのイテレータに似た処理をするには別のオブジェクトを作らないといけなくて面倒なんです。Rubyのブロックは「1つ取ってきて渡して処理して、また次に1つ取ってきて処理」というモデルで、シンプルで分かりやすいというメリットがあります。2つ配列があって1つずつ取り出してきて処理するというのは、面倒だったんです。言語によっては外部イテレータとか、カーソルオブジェクトといいますよね。いうポインタみたいなものが以前はGeneratorというライブラリで提供されていました。それをもっと手軽に、軽量に行う仕組みが1.9でEnumeratorに導入されました。1.8にもEnumeratorとGeneratorという2つの似たようなライブラリがあったんですけど、それが1.9ではEnumeratorに統一され、組み込みになりました。ここら辺、ああ、Rubyはやっぱり“大クラス主義”だなって思いますね。似たような機能のものを大きなクラスにまとめるという方針です。あると覚えるのも大変だし、使い分けられないから、まとめちゃう。「配列」といったとき、普通の言語ではpushで要素を加えたり、popで要素を取り出して配列の長さを縮めたりできませんよね。CやJavaの配列は固定長なので、できません。リスト構造を使うか、なければ自分で作ります。Rubyでは「似てるから1つにしちゃえ」という発想で配列がリスト構造のように振る舞い、伸び縮みします。Rubyでは、スタックとか、キューとか、そういうデータ構造も含めて配列の「Array」というクラスに全部突っ込んじゃってるんですよね。データ構造の授業をRubyでやると大変なんです。スタックはこういう風に作るんですよといって、ポインタが次の配列を指してって説明しますよね。うーん、ぼくは物事を始めるのにモーメントが大きいタイプなんですよ。Rubyでもまだまだできることがあるしなぁ。Rubyの代替となるような言語は作ってみたいですね。Rubyにも良い仕様、悪い仕様ってありますよね。研究者なので、例えばいまだったら並列向けの仕様を最初から入れると、どうなるんだろうという技術的な興味があります。笹田君は並列が専門の人だしね。——笹田さんは以前、こんな話をされていましたよね。プログラミング言語の新しいパラダイムをピュアに取り込むと、現実のプログラマには受け入れられなくて、Rubyのように新規性と伝統的な言語のスタイルや発想をバランスよく取り入れたものが普及する。同じように、並列化というテーマでも、あまりピュアに最初から並列化を目指すのではなく、うまいバランスがあるのではないか、と。ええ、だからRubyはRubyでバランスよく並列処理は取り込んでいけばいいと思います。言語レベルで変えたらどうなるかなっていうことにも興味があります。これは思考実験で終わるような気もしますけど。既存言語の並列版といえば、こんな例もあるよ。Satherって言語があるんですけどね、そのSatherの並列版としてpSatherというのがあるんです。パラレルSather。pSatherではparloopというforの並列版に相当する構文が増えています。forのようにループを回すのではなく、並列でドカンと走らせることができる。ほかにもpSatherにはアクターモデルを実現する文法が追加されていたりします。そのへん、どんな実装がいいんでしょうね。少なくとも、いまのRubyのインスタンス変数の持ち方だと、厳しい気がする。いや実は、そこはあまり問題ではないんですよ。やるんだったら、文字列を全部変更不可にするぐらいの変更が必要ですね。それをやっちゃうとプログラマには不自然だし、使いづらいでしょうから、むしろRubyのような普通のプログラム言語が中に閉じているものが並列に動くのがいいのかなという気がします。いまのRubyは大域的に何でも出来ちゃうので、それを狭めて並列化する、というイメージです。——それはまつもとさんが楽天でやってらっしゃるFairyプロジェクトみたいなものでしょうか。あれは言語に手を入れるというよりも、システムを提供するタイプの並列ですね。並列というより分散システムです。グーグルのMapReduceとかGFSを意識しています。Language)を用意する形になるかもしれません。——Rubyの並列版を作って「pRuby」を名乗れば晴れてP言語の仲間入りですよ。1.9について教えてくださいと2人に取材を依頼し、秋葉原のカフェで1時間ほどお話しいただいた。お昼どきだったので、取材を終えてから記者も食事をご一緒させていただくことになった。お昼の12時半ごろに入店して、店を出たのは実に夕方の4時過ぎ。あまりに長時間話し込んでしまい、まつもと氏は飛行機に乗り遅れてしまった。所々で2人の会話に割って入る私の質問に丁寧に答えていただきながらとはいえ、4時間にも渡って、まつもと氏と笹田氏は延々と技術論を続けた。Rubyについてばかりでなく、並列Rubyの可能性や、米アマゾンが取り組んでいる分散コンピューティングの論文の話、100年後のプログラミング環境の話、普段使っているPCやソフトウェアの話と話は弾んだ。プログラミング言語としての可能性を追い求め、知的探求心から開発に情熱を燃やす2人を見ていると、これこそ1990年代以降にフリーソフトウェアが大きな力を持つに至った原動力なのではないかという思いが強くなった。いまのままRubyに関わって食べて行ければそれでいいと笑う欲のないまつもと氏にしろ、実装してみたいアイデアやプランに溢れた笹田氏にしろ、現在急速に進んでいるRubyの受容に対して意外に恬淡としている印象を受ける。Rubyが普及し、結果として世の中に役立つことは喜ばしいにしても、もともとの動機は、むしろ知的好奇心。記者には、「それがぼくには楽しかったから」といったLinux開発者のリーナス・トーバルス氏の姿に、まつもと氏らが重なって見える。いつまでも楽しそうに議論している2人を見て記者は、こう思った。「これは、パズル好きの人が好きなだけパズルをやり続けている状況だ」。1.9の位置付けを整理すると、こうなる。1.9系というのはパズルを構成するピースすら作り替えるようなもの。1.9というのは当面、これからRubyを使ってみようというユーザーのためのものというよりは、知的好奇心から使ってみよう、中を覗いてみようという人たちのためのものだ。それは、自分たち同様のパズル好きのために、まつもと氏を中心とした開発メンバーらが用意したクリスマスプレゼントと言えるのかもしれない。World!」プログラムで使われる、「printf()」「main()」関数の中身を、デバッガによる解析と逆アセンブル、ソースコード読解などのさまざまな側面から探る連載。World!」プログラムで使われる、「printf()」「main()」関数の中身を、デバッガによる解析と逆アセンブル、ソースコード読解などのさまざまな側面から探る連載。(2017/7/6)日頃発生する“面倒くさい業務”。簡単なプログラミングで効率化できる可能性がある。Excel」で使えるVBAを紹介する。