編集注。この記事は 2010 年に開催された RubyKaigi2010 での LT をるびま誌上で再現したものです。
まず、RubyKaigi の LT では最初に「Google Wave 入門」をさせていただき、おかげさまでジュンク堂 RubyKaigi 支店の「Google Wave 入門」は売り切れとなりました。この場を借りてお礼のふりをした再度の宣伝をさせていただきます。右の画像がリンクになっていますので、よろしくお願いします。
さて、本 LT では元々はタイトルの通り私が parse.y を少しだけ弄って作った少し変わった Ruby を紹介する予定でしたが、資料を作っているうちになんとなく趣旨が変わってきてしまったのでタイトルを変更させていただきました。また、8 月は何かと気苦労が多くて 4 つ目を作る暇がなかったのでサブタイトルも修正します。
Ruby は 1996 年 12 月 25 日に Ver. 1.0 がリリースされ、その後も 2002 年のクリスマスには 1.6.8 、2004 年のクリスマスに 1.8.2 、2007 年もぎりぎり地球上のどこかがクリスマスであるうちに 1.9.0 がリリースされました。そして昨年、2009 年のクリスマスです。勘違いしている人も多いようですが、実は昨年のクリスマスにも新しい Ruby がリリースされています。それが XRuby です。
XRuby の X は XML を意味し、その名の通り XRuby では XML リテラルが利用可能になっています。
http://github.com/technohippy/xruby
phone_book = <?xml>
<phonebook>
<entry>
<name>Burak</name>
<phone where="work"> +41 21 693 68 67</phone>
<phone where="mobile">+41 79 602 23 23</phone>
</entry>
</phonebook>
</xml>
puts phone_book.class.name
#=> REXML::Document
puts phone_book.elements["//phone[@where='mobile']"].text
#=> +41 79 602 23 23
puts phone_book.elements["//descr/a"].attribute('href')
#=> http://acme.org
実装は parse.y のヒアドキュメントのところをいろいろとコピペしてちょっと修正しています。
このクリスマス Ruby のおかげで C 言語がよく分かってなくても、コピペと想像力と気合いで Ruby の改造は意外となんとかなることが分かったので、XRuby 以外にもいくつか作ってみました。
二つ目は ORuby です。O は Objective です。メソッド呼び出しをオブジェクティブに書けます。普通の Ruby と比較するとこんな感じ。
http://github.com/technohippy/oruby
# 普通の Ruby
require 'date'
birthday = Date.new(1993,2,24)
if birthday == Date.today
puts "Happy birthday, Ruby!"
end
# Objective Ruby
require 'date'
birthday = %o{ Date new:1993 month:2 day:24 }
%o{ (birthday = Date today) ifTrue:[Kernel puts:'Happy'] }
%o{…} が今回導入されたオブジェクティブリテラルで、オブジェクティブリテラル内では Ruby のメソッド呼び出しをまるで Objective-C のメッセージ式のように書くことができます。birthday という変数がオブジェクティブリテラルの内外でやり取りできているのが本例の見所です。
これだけだといまいちなのでさらに進んだ例。
# 普通の Ruby
class MyClass
def my_method(num)
while 0 < num
if num % 2 == 0
puts num
end
num -= 1
end
end
end
MyClass.new.my_method(10)
%o{ Object subclass: 'MyClass'. }
%o{ MyClass compile: '
my_method: num
[num := num - 1. 0 < num.] whileTrue:[
val := (num % 2).
(val = 0) ifTrue: [
Kernel puts: num.].].'}
MyClass.new.my_method(10)
クラス定義もオブジェクティブに書く事ができます。見所はオブジェクティブに定義したクラスとメソッドを、オブジェクティブリテラルの外の普通の Ruby の構文で利用できているとこです。
実装はこんな感じです。
%x{} とかをコピペしてゴニョゴニョしました。このオブジェクティブリテラルは Smalltalk で著名な梅澤さんにも「Objective Ruby、もう標準でRubyに入っていていいんじゃないかと思いました。」と言われるほど大きく期待されています。Ruby 2.0 の目玉機能としていかがでしょう?
最後のオレオレ Ruby は FRuby です。F は Fuzzy の略で、その名のとおりなんとなくあいまいに実行したりしなかったりする条件文が利用できます。
http://github.com/technohippy/fruby
count = 0
1000.times do
if true then
count += 1
end
end
puts count #=> 1000 (100%)
count = 0
1000.times do
if true probably
count += 1
end
end
puts count #=> 839 (80%)
count = 0
1000.times do
if true maybe
count += 1
end
end
puts count #=> 471 (50%)
count = 0
1000.times do
if true perhaps
count += 1
end
end
puts count #=> 188 (20%)
FRuby では if then 以外に確度に応じて probably、maybe、perhaps が利用可能です。
実装はこんな感じになります。
if then を処理してるっぽい関数に無理やり確度を表す引数を追加して、条件文を Fuzzy な感じにしました。C 言語を知らなくても NEW_FCALL とか使えば普通に Ruby のメソッドが呼べるので素敵です。
この FRuby は Ruby が海外で広まり始めたころに if not を unless と書けることがウケてたと聞いて、こう言うのもウケがいいんじゃないかなと思って作ったものだったので、発表で期待通りに海外組が笑ってくれたのがなかなかうれしかったです。
以上のとおり parse.y を適当にコピペして新しい Ruby を作るのは意外と簡単だということが分かりました。コツ (?) は
の 3 つです (ただし上記にいくら習熟しても永遠にコミッターにはなれません) 。
これまで我々はずっとクリスマスにサンタクロースの格好をした Matz にプレゼントをもらってばかりでした。Ruby が生まれて今年で 17 年。17 年という年月は Ruby が生まれたときに小学生だったとしても今では家庭を持ち子どもがいてもおかしくない、それだけの年月です。そろそろ私たち Ruby ユーザーも幼年期を終え、クリスマスプレゼントを受け取る側から、贈る側へと変わる時ではないでしょうか。ネタ次第では Ruby の改造もわりと簡単だということを我々は既に知っています。ということで……
今年からクリスマスはユーザーが勝手 Ruby を作って公開する日にしませんか?
Ando Yasushi (Seesaa Inc.) たぶん史上最後の Google Wave 本の著者。あとおっぱいとかカリスマとか