まつもとゆきひろ『プログラミング言語Ruby』を大いに語る

第5回 ブレーキが外れた後半戦 5から10章

|

前回までのあらすじ
『プログラミング言語Ruby』の生まれた経緯から書籍へと入ります。言語仕様の解説部分では、リリースマネジャーの卜部さんでさえ知らなかった内容が登場するなど、なかなか侮れない内容。Ruby初心者も上級者も楽しめる内容。今回はよりディープなRubyの世界へと移ります...

5章 文と制御構造

ch05.jpg

Rubyって文と式とあんまり区別がないんですけど、普通のプログラミング言語で文といわれているようなものとか、制御構造と言われているものについて解説しています。

―この辺から発展的内容って感じですね、4章までは、どちらかと言えばRubyの基礎的な内容でしたが、ここからですね、なんて言うんですかブレーキが外れてきて、

ははは。

―この章の一番最後の方にスレッドとかファイバとか継続について書いてあるんですけど、ファイバに関して言うと、この本の原著が最初に出たのが2008年1月。このころは、まだファイバが出てきたばかりで、これ本当に書くのか? という感じで。2007年の11月に飛行機の中でドラフト版を読んで「ファイバに何ページも割いてある」と言ったら、(まつもとさんに)「ちょ、ちょっと見せて」とか言われて。まだ当時そんなに固まってないのに「こんなに書かれるとヤバい」と。

ファイバ作っている本人でさえ嫌がると。

―そういえばファイバの事が詳しく書いてあるのもこれが初めてですね。

Rubyのファイバについてはこれが初めてですね。

―そんなに頻繁に使う機能ではないのですが、いろいろなところで使われている機能です。いろんな値の渡し方の例とかが豊富に載っているので参考にしてください。

ファイバって結構応用範囲の広いみたいで、「NeverBlock」ってのはノンブロッキングI/Oとファイバを使って、マルチプレキシングをすると1。例えばたくさんのスレッドを使うと、けっこうコストがかかるんです。というのは、スレッドが起動するときに1メガだったか、何メガだったかの領域を割り当てるので、そうするとスレッドを1000個作ると1ギガとかメモリを使っちゃう。あまり多く作れないんですよ。イベントドリブンモデルはそういう問題はないんですけど、

―書きづらいですよね。

そうですね、ちょっと書いてまたイベントループに戻してと。それで、NeverBlockっていうのはファイバを使っているおかげで、スレッドと同じようにシーケンシャルなコードが記述できる。でもスレッドを使わないでI/Oの多重化を、イベントドリブンのような形でできる。スレッドと違って、割り込みでコンテキストが変わることがないので、非決定的な問題、タイミングによって起こるバグがあんまり発生しないという。

―「ロックしなくてもいいか?」と言うとそうでもないんですけど、だいぶ楽になっている。

ホントにシェアするところは駄目なんだけれど。そういう結構いいクラスで、データベースI/Oなんかに使われていて、

―多分皆さんにとって重要なのは、MySQLのアダプタとかがあって、ActiveRecordの中に挿せるというとこが重要なんだと思います。

ベンチとったら何倍速かったとか、そういう(blogの)エントリもありますね。ファイバ、作った本人もこんな応用のされ方をするとは思ってなかったというのはありますね。あとは、Revactorという名前の、Erlangっていう関数型プログラミング言語があるんですけど、あれにに似たアクタモデルがありますね2

―アクタも確かにね、確かにいろんなアクタが待ったり待たなかったり。

で、それを下のレイヤがイベントドリブンでファイバに切り替えて行こうと。

―Erlangみんな大好きですね。

Erlangみんな大好きで、「Erlangどうやって真似しようか」ってみんな言ってる感じですね。

―Erlangの何がいいんですかね?

Erlangね、パラレルにできる問題があると極端に(性能が)延びるんだよね。8コアのサーバマシンで、各CPUに上手に分けられる問題であれば、シングルコアに比べて6倍とか7倍とか速くなる。もちろんそういう問題は限られるんだけど、そういう問題に出会った時にインパクトが大きいのでみんな喜んじゃう。だけど、そういうのが効かない問題だと、とたんに遅くてですね、文字列処理なんかはRubyに勝てるわけないんで、こっちはそればかり10何年やっているので、それを見て「Erlang使えねぇ」とか言ってるわけなんですけど。ハマると早い感じです。

ただ、マルチコアの環境がだんだん増えているので、状況が変わってくるかもしれない。マルチコアの環境を最大限に活用するには、ソフト側の対応が必要なので。昔はどんどんCPUが速くなるので、同じソフトウェアでも(マシンを)買いかえれば速くなったんだけれど、マルチコアだとソフトウェア側の対応が必要で、

―本質的に危険な状態とかありますから。

そういう理由で、書きやすいプログラミング言語やライブラリが期待されているというのはあるみたいですね。ただ、普通のプログラマがそこに到達することはあんまりないと思いますね。

1 NeverBlock
「マルチプレキシング(Multiplexing)」は多重化のことです。

2 Revactor

6章 メソッド、proc、lambda、クロージャ

ch06.jpg

―この章が一番ブレーキが利いてない、暴走している感じですね。そもそもprocとlambdaとわかれていますけれど、procとlambdaというものがあるということも、ほとんどのRubyプログラマは知らない訳で、俺もこれを読むまで知りませんでした。

すいませんprocは継子です。

―でも1.9からは一応あることが分かる感じに...

でも、「なくてもいいじゃん」という感じですが。

―procとlambdaは何が違うのというのは、この本を読んでいただきたいですね。具体的にどんなことが違うのかとか、あるいはメソッド、メソッドはもちろんメソッドオブジェクトがあるわけですけれど、それをprocとlambdaに変換したり、逆にprocとlambdaから(メソッドオブジェクトを)作ったりというやり方にも話が及んでいて、とてつもなくメタプログラミングに話が近づいていて、最後の方はFunctional Programming、関数型プログラミングにも話が及んでいて、こうなって来るともうほとんどメタプログラミングの嵐で、本の中にも「ここは読まないでいいです」というようなことが書いてあって...

―「何なんだこれは」と思いながら、読んでる方はとても面白く読めるという。

「あなたの知らないRubyが垣間見える」という。

―あ、そうだ。この章の扉絵はいきなりevalと書いてあって、この辺からも怪しさが漂い出しているという。

7章 クラスとモジュール

ch07.jpg

―実はこの章全体がひとつのチュートリアルになっていて、最初はちいさい、何も機能がないようなクラスから、必要なものをどんどん足していってと、最初から読むようなタイプになっています。ですが、最初から超ハイスピードで進んでいって、なかなか激しい内容ですね。(イラストの)上の方を見ると特異クラス定義が書いてあり、絵からもそんな感じが出ていますね。
「特異クラスを作ったときにどうなるのか」みたいな話が書いてあって、国内ではblogで特異クラスに関する話がずっと議論されてました。この本には反映できてないんですが、そんな感じのことがかなり詳しく書いてあります。そのほかにもクラスメソッドとかクラス変数とか、皆さんが使っておられることも書いてあるわけで。

ですね、楽しい。

8章リフレクションとメタプログラミング」

ch08.jpg

―これは、携帯電話? 鏡...鏡で自分を見ている感じかな。

リフレクションだから。

―そうですね。

「リフレクション」って言葉には、「反射」とか「反省」とかいう意味があるんですけれど、自らを省みるわけですね。Javaなんかで、鏡を通すように自らがプログラム自身の情報を見る。そういうのを「リフレクション」と言ったりします。「メタプログラミング」という言葉の「メタ」というのは一段(抽象度が)上のというか、プログラミングそのものを操作するプログラミングが「メタプログラミング」。だいたい同じようなものなんですけど、プログラムそのものを見たり、操作したりする機能が「リフレクション」で、そういうリフレクションの機能を使ってプログラムそのものを書き換えるようなプログラミングスタイルが「メタプログラミング」という感じです。

―Yuguiさんが良く言う「黒魔術」というやつで、思いもよらないことが、思いもよらない行数でかけたりとか。

「黒魔術」という言い方について反論ですが、役に立たないかというとそんなことはなくて。ActiveSupportとか、みんなが使っているメタプログラミングという意味では、ActiveRecordが一番実用度が高い気がします。データベースのレコードに対応するオブジェクトがあって、で、そのオブジェクトをActiveRecordBaseから継承するだけで、クラスが対応すべきテーブルの名前をクラス自身の名前から取ってくる。それってのはリフレクションによって「私の名前は何?」とクラス自身がきいている訳ですね、内部で。その聞いた名前をデータベースの中で複数形に直して...ってのがケッタイ。

―あれはオフにできる

でも、逆らうと痛い目にあいそうなんで。

―どうなんですかね?

実際、僕はあまり逆らったことがないんで分からないんですが、

―「index」とか複数形になった時に困るんですよね。DBではよく使う名前なので。

「indexes」か「indices」とかね。で、タプルというかレコードの様子を見て、レコードに対応したフィールドを勝手に設定するという。だからデータベーススキーマの中だけにクラスの構造の記述があるということなんですけど。それが実際に出来るのは、自分の名前を見て、対応するテーブルを探して、対応するテーブルのスキーマを見て、自分のメンバというかフィールドを追加することができるという、メタプログラミング、プログラミングそのものを操作するという機能によってできるようになっている。

―やりすぎ感があるという

Ruby on Railsを作ったDavid Heinemeier Hansson(DHH)はデンマークの人で、Railsを作る前はコペンハーゲンの大学でPHPプログラマをしていたんです。Webをいっぱい書いていた。僕は2001年と2003年にデンマークで開かれたJava and OOに行ったんですけれど、確か2001年にPHPプログラマのDHHにあってるんです。

その後、これは37 Signals3の社長さんがPHPでプログラミングしたいって言う時に、DHHがPHPを教えてあげていた。この社長さん、しばらくDHHからPHPを教わった後で「僕がやるよりも、お前に仕事出した方が早い」といって、デンマークにいるまま、シカゴの37 Signalsのプログラマとして在宅勤務で働くようになった。

それで37 Signalsのプログラムがだんだん複雑になっていくうちに、ちゃんとしたフレームワークが要るという話になって、ちゃんとしたフレームワークを書くにはちゃんとした言語でなくてはならないとDHHが主張しはじめて。みな止めたらしいんだけど、凄い強引な人なので、「これでやるんだ」と押し切って、「PHPで出来なかったメタプログラミングやるぞ!」って、本当にブレーキ壊れてますね。人のこと言えないけど。
それでメタプログラム満載のフレームワークを作った。Rubyって「オープンクラス」といって、既存のクラスにどんどんメソッドを追加できるんですけど、既存のクラスにメソッドを追加できるなら、どんどん追加したらすっげえ便利になるぞって、がーって凄いたくさん追加して。あの2.weeks.agoとか、何なんでしょうね。

整数クラスの2にweeksという名前のメソッドを追加すると、14日分の秒数を返すんです、整数でね。それにagoと書き足すと、現在の時間からその秒数分だけ前の時間のTimeオブジェクトを返すというメソッドを、あとから追加しているわけ。

「1.weeks.agoじゃおかしいじゃないか」と返したら「そんなこともあろうかと思って1.weekメソッドも定義したから」とかって。weekメソッドとweeksメソッドの両方あるというんですよ。

―どうかと思いますよね。でも、あれが便利って言う人もいて、

後のRubyにおけるDSLのトレンドの先鞭をつけた感じで。

―幾つかはRubyにバックポートされたものも、Method#to_procとか。

よい影響もあって、そういう便利な書き方、柔軟な書き方ができるから「Rubyすげえ」とか、今Rubyあちこちで評判になってたりとか、いろんなところで使われるようになっている。2003年までは知る人ぞ知るというマイナー街道まっしぐらだったんだけど、欧米では2004年くらい、日本では2005年から2006年くらいにRuby on Railsが盛り上がって、こっちは「なんだろう」という感じで。

「10倍論争」とか2004年からありましたね、これもオライリーですね。オライリーblogの中で、典型的なJavaアプリケーションフレームワークを使った開発よりも10倍生産性が高いという記事があって、Ruby on Railsを作ってるひとではなくて第3者なんだけれど、それを書いたのがオライリーblogだったから、オライリーがお墨付きを与えたように見えたかもしれない。それでJavaの連中が怒り狂って、「10倍生産性が高い」とは何事だと。

―まあ、それはそうですよね。例えばErlangの人たちに「10倍生産性が高い」って言われたらキレますよね。

まあ、場合によってはね(笑)。

―(あの記事では)「場合によって」ではなくて、「10倍だからこれを使わないのはお前らどうかしてる」みたいな、ちょっとフレームっぽいことを書かれてしまって。

10倍生産性が高かったらマイナーだなんて言っている暇ないよね、という煽りだったので。そもそも生産性って測れないじゃないですか。「10倍気分がいい」とかね。それで、こういうことがあったので、その後、検証するときに「Struts使えばそうかもしれないけど、俺のこのフレームワークを使えばこうだ」と言い出す人もいたりして、互いに刺激を与えあったところがあったりして4

その後、まあ2005年くらいを通じて「何倍かは分からないけれど生産性は高そうだ」と。あと、(その過程で)皆がRuby on Railsを実際に見てみた結果、「結構いいかも」と思ってくれた人がそれなりにいたり。
だいたいのオープンソースソフトウェアってマーケティングが下手なんだけど、Ruby on Railsは例外的にうまくて、論争を通じて人を集めたりしている。DHH、マーケティング上手いというか議論好きで、炎上しているところに自分からガソリン抱えて飛び込んで行く感じで。

―上手に燃えあがらせますよね。それで燃えた後に何かが残るのがすごいですよね。燃やし尽くさない。

もう一つが、DHHがブラジルのオープンソースのカンファレンスでデモをしたビデオがあって、何も準備していないところにPCとスクリーンを出して、「今からblogのソフトウェアを作ってみるから」と。何も仕込んでないんで「データベースの定義どうしようか?」とPhpMySQLAdminを使いながら、ブラウザの中でスキーマを定義して、15分後にはblogのソフトができてて5。2004年の段階で15分でWebアプリケーションを1本書くというのは驚異的な速さだった。今ではそうでもないかな。

―いや、それでも早い方だと思いますけど。

そういう「百聞は一見にしかず」っていうのを見て、これで本当にできるかもしれないと思った人たちが多くいた。その2つ、さっきの大論争と、ビデオという二つがRuby on Railsの人気のきっかけだったのではないかと思っています。

―Ruby on Railsがメタプログラミングを使ってるので、Rubyプログラマのほとんどは、そうとは知らずにメタプログラミングを使ってますね。

そう、縁の下の力持ちで、こういう不思議な生産性が実現できていると。Ruby on Rails以降は、こんなことやればいいんだという(認識が生まれた)。最初の一歩が大事なので、いろんなところから真似をして、新しいものが出てきた。CakePHP6もそうかもしれないし、Symfony7もそうかもしれないし、Javaの方だとGrails8とかTrails9とか。

―雨後の筍のようにいろんなものが出てきた。

名前に「Rails」ってつけばいいってもんじゃないだろうって感じもするんだけれど、そういうのがいっぱい出た時期があって。でも全部が全部生き残るわけではない。(Railsも、)実は内部でリフレクションとメタプログラミングが(使われてて)。そういう生産性を実現するために、この章を理解しておくと、あなたも明日のRailsを作れるかも、ってホントかな?

―Railsほどでかいものを作るとなると気構えないといけないけれど、ちょっとしたDSLをこんな風に作るといいよということが多少は書いてありますので、参考になるかと思います。

3 37 Signals
Basecamp、Backpackなど、シンプルなWebベースのビジネス支援ソフトを提供するソフトウェア企業。

4 一連の経緯が「Matzにっき」の以下のエントリにまとめられています。
http://www.rubyist.net/~matz/20050321.html

5 RailsのWebサイトでアップデート版が公開中。これ以降「○○分で作れる○○」というビデオが爆発的に流行りました。
http://rubyonrails.org/screencasts

6 CakePHP

7 Symfony

8 Grails

9 Trails

9章 Rubyプラットフォーム

ch09.jpg

―ここでさらにまた分かれて、9章はリファレンスっぽい話になります。この辺がもともとの『デスクトップリファレンス』から多少引き継がれているという部分ですかね。

んー、気持ちだけ。この絵は何なのだろうね?

―プラットフォーム?

プラットフォームね。何か降り立っている。

―9章は、これまで語られてこなかったことが山ほど語られていて、とても重要なんですが、

何を語ればいいんだろう?

たとえば、Rubyの正規表現がRubyの1.8と1.9では実装が変わって、仕様も変わって、1.9の方ではこうなっていますよ、ということが書いてあったりとか。あるいはI/O、ファイル周りの話がこれまでぜんぜん書いてなかったところが書いてあったりとか、それも含めて、量も量なのでそんなに詳しくは書いてないんですが、こんあものがあるよということが網羅的に書いてあるので、字引き的というか、ふと「こんなことをするにはどうすればいいんだろう」と思った時に読む感じのリファレンスですかね。

10章 Ruby環境

ch10.jpg

―この章が最後で、「Ruby環境って何?」って話ですけれど、これはプロセス外とのやり取りですね。例えばコマンドライン引数だとか。そういうことが書いてあって、これもリファレンスっぽいですね。コマンドライン引数も増えたり減ったりしていて、やっぱり、そのM17N周りで変わっていますので、分かっていたつもりでしたけど、やっぱり知らないオプションがあって、「こんなのあったんだ」って。

すいません。一応、僕が知らないことはなかったですけど。当たり前?

―この絵はなんだろう?

なんか王様っぽいですね。いや、分かんない。whyの絵は分かんない。今度聞いてみよ。

(つづく)
本文中でつかわれているイラストは書籍『プログラミング言語Ruby』のために why the lucky stiff さんが描いたものです。今回の記事のために、whyさんの許諾を得て転載しています。

アーカイブ