松江Ruby会議05に参加してきた

2014/3/15(土)、島根県松江市にてMatsue.rb主催の松江Ruby会議05が行われた。それのゲスト講演をしてきた。
島根県がやっているRuby合宿でDXRubyが使われているという繋がりでDXRubyに関する講演の依頼が来たので、ちょっと喋りに行ったという経緯である。
懇親会含めていろんな人と話したし、こっちで細々とライブラリ作ってるだけではわからない松江の現場の話を色々と聞けて、非常に楽しかった。まとめるにもどうまとめたらいいのかよくわからない感じになっているので、何回かに分けて感想などを書いていくことにする。
まずは講演の感想から。

Matzの基調講演「Prepend Your Class」

Ruby2.0とRuby2.1での新機能について、及び、Ruby2.0で追加されたModule#prependの話。
Module#prependはこのブログでも過去記事で軽く紹介しているし、Ustreamで録画されているのでそれを見るとたぶんよくわかる。
Matzの話ではアスペクト指向を実現するために必要な機能だと言う感じで、なにやら難しくてわからないのだが、後の前田さんの講演で具体的に使用されている。といってもこっちも難しい。
重要なのは継承階層の下側に追加されるという点で、複数のクラスに対して共通したコードを最も優先度の高いところに追加することができる。includeが存在しないメソッドを追加する用途で、prependは存在するメソッドをオーバーライドする用途である、という部分か。
DXRubyでどう活用するかは難しいところで、少なくとも最低対応バージョンが2.0にならないと使いにくい。ま、使わないといけないわけでもないからいずれ何かいい用途が思いついたらまた試すという感じに。

俺の講演「DXRubyのご紹介」

DXRuby関連で初めての講演なので、軽くゆるく紹介する感じで、って思っていたのだが、松江Ruby会議05の参加者は化け物みたいな人がゴロゴロしてたので舐めてかかっていたかもしれない。そもそもMatsue.rbメンバーのDXRuby関係者率が高くて紹介しなくても知ってるよって感じ。参加者には知らない人もおったと思うけど。
USTは恥ずかしいのでここには書かないが、上のんから辿れば出てくるのであまり意味は無い。どのように話したらどのように見えるのかというのが全く未体験ゾーンだったのでお見苦しい姿を見せてしまって申し訳ない。などと意味不明の供述をしており。
さて、話した内容は軽い紹介程度ではあったが、ともかくシンプルで初心者フレンドリーである、という点に絞ってみた。実際にはそのように使えるものにするためにそれなりの時間と作業量がかかっている。簡単に使えるものは簡単に作れるわけではないのだな。後で他の人と話したときにはそういう質問も出ていて、実装的な話とか、最適化関連の話とか、あそこにいた人たちはそこから話し始めてもいいレベルだったのだろうなと思った次第。
後半のライブコーディングは、TeraPadひとつで0からコードを書いてブロック崩しを15分で作るというネタ。使ってたノートPCは借りたもので、「RubyとDXRubyとテキストエディタがあればいいです」って言っておいたらほんとにそうなった。知らない開発環境を入れられててもたぶん使えなくて焦ることになっただろう。テキストエディタだけで作れるという実演にもなったのでよしとする。
実は時間が足りなかったときに3分間クッキングよろしく完成品を出そうかとも思っていたのだが、何も準備しないことにした。勇気と無謀は違うものだということを身を持って知ることにならなくてよかった。
ライブコーディングのネタはいくつか考えていて、10〜15分で作れるものとして、簡単なシューティングゲームとか、簡単なジャンプアクションなども検討していたのだが、シューティングはクラス定義しないと辛いし、ジャンプアクションはマップ作ったりするのが面倒なのでやめておいた。ブロック崩しが一番手軽だった。それぞれ2回ほどコードを書いて試したというのは裏話である。ブロック崩しは最初に書いたものがライブコーディングで書いたものとほぼ同じ内容・時間で書けていたので、完全にぶっつけ本番でも15分でいけただろうと思う。しかしそれは完全に無謀な試みである。
貧相なものができあがっていたわけだけども、俺が目指すのは簡単に豪華なものが作れるライブラリではないので、このライブコーディングそれそのものがDXRubyとはどういうものかを如実に表していたのではなかろうか。

橋本さん「ちょっとるりまでも更新してみようか」

bitclustを使ってるりまを更新する作業のライブコーディング。なんか難しくてよくわからんかったのだが、ブラウザがるりま用カスタムだったりRubyのソースまで見てるりまを更新するというのは凄味があった。
普段、リファレンスマニュアル書くの面倒だなー誰か作ってくれないかなーとか思っていたが、作ってる人じゃない他の人がマニュアルを書くのはそれはそれで非常に大変な話なのだと言うことがよくわかった。
これぐらいすごい人がマニュアル書いてくれたら確かにできるんだろうけど、そんな人がDXRubyのマニュアルを書くのはまず間違いなくオーバースペックである。
がんばって書きます。

木村さん「RubyMotionいつやるの?」

RubyMotionでiOS用のアプリを作るという恐ろしいライブコーディング。そこに書かれたコードで実際にiOS用アプリが動くというのはライブコーディングならでは。るりまのやつもブラウザで見るマニュアルが変わっていくし、これは面白いなあ、と思った。俺のんも貧相なブロック崩しが少しずつできていったので楽しんでもらえたのかしらん。
そういえばRubyMotionというのは存在は知ってたけどコード見たのは初めてだった。Objective-Cから呼ぶメソッドをRubyから叩けるのだな。クラス名やメソッド名が恐ろしく長かったのはそういう文化なのだろうけども、Rubyの文化とは明らかに違うので好みの分かれるところだろう。
直前にエディタを変更した都合で最後のほうは時間が足りなくて動くコードをコピペしてたけど、よく考えると少しずつコピペして動かして見せるのとキーを叩くのは理論的には違いが無い。見ている人が「こうやって開発するんだなあ」と感じる量が変わるという感じか。ライブコーディングの価値はまさにライブ感なのか。
この後の前田さんが「ライブコーディング失敗する人が多いので準備してきました」的なことを言ってたのは、動くかどうかよりもライブ感を大事にしていたと言うことなのかな。

前田さん「Module#prependとRefinementsで遊ぶ」

Matzの発表であったprependをベースに、アスペクト指向的なコーディングをするという発表。用途として想定されているログの取得を実現する、という内容だった。Refinementsは後のほうでちょこっとだけあった。
実際のところ、prependは今のところそんなに使われている感じは無くて、たぶんきちんと設計されたクラス群に対して使うものというのがあって、ちょっとしたコードでは使いにくいのもあるんじゃないかと思っている。動作の理屈自体は簡単なものだから、例えばDXRubyでゲームを作る場合に有用な使い方というのもありそうではある。
Refinementsを使った例はちょっと面白かった。標準のクラスのネームスペースを汚染しないように拡張して局所的に使うことができる。これはDXRubyでは例えばSpriteの配列に対してupdateするのに、Sprite.updateを使うんじゃなくて、Array#updateを追加するような暴挙を、自分のコードの一部分に限定してできるわけで、うまく使えば便利そうである。このような使い方ができるのがRuby2.1からというのが残念だが、いずれRuby2.1がいくらなんでもそれは古いやろーと言われる時がくると思うので、知っておくとよい。
あと、リファクタリングしてクラスを移動したらselfが変わってしまう問題の対策とか、めっちゃメタプログラミングでクラスやメソッドを抽出したりするあたり、勉強になる。

高尾さんと岩石さん「takaokoujiとrockzeroのぶつかり稽古」

最初の簡単な問題は簡単だったが、いきなりFizzBuzzになってレベルが跳ね上がった。高尾さんがお父さんみたいだったwいいコンビである。
4x4のルービックキューブって初めて見たけどあれは無理だわー。3x3でも無理なのに。

Ruby.Jr

ライブコーディング大喜利には参加せず、Ruby.Jrの発表を見ていた。機材がMacということもあって、RSDLを使っていたようだ。RSDLはMacで動くようにSDLを組み込んだRubyで、くまりゅうさん作。くまりゅうさんはRikoの人。ずっと前にRubyでゲームを作る発表Ruby会議2009でしていた。当時はRubyでゲームが盛り上がっていて、カンブリア紀の進化の爆発のように色々なライブラリが出ていた。DXRubyをSourceForgeで公開したのもちょうどこの頃で、これは偶然である。なんせDXRubyのプロトタイプは2005年。まあそういう話はまたいずれ。
ともあれ、Ruby.Jrの発表会で若い子たちが自分で作ったものを一人一人発表していた。Ruby.Jrは中学生Ruby教室などに参加したあと、継続して学ぶ場として月1回、全7回というペースで行う勉強会で、当日は最後の発表の日だった。終わる頃には参加者とスタッフの人と俺と野坂さんぐらいしかおらんかったような気が。Ruby合宿みたいな豪快な成果物じゃないからしょうがないのかもしれんけども。
見てて思ったのは、SDL1.2では辛いな、ということ。ぶっちゃけ、速さは力だな、と。
Ruby用にSDL2.0のライブラリが出ると状況も変わるんじゃないかと思う。開発されているものがひとつあるのは知ってるけど。

おしまい

松江市島根県の取り組み、こっちにいてはわからないような現場の感覚や状況など、そういう話は後日。
それから、DXRubyに対するリクエストや質問、使ってる人たちの言葉なども生で聞いてきたのでそういう話も後日予定。

最後に、ライブコーディングで書いたコードをのっけておく。

require 'dxruby'

bar = Sprite.new(0, 460, Image.new(100, 20, C_WHITE))

walls = [Sprite.new(0, 0, Image.new(20, 480, C_WHITE)),
         Sprite.new(0, 0, Image.new(640, 20, C_WHITE)),
         Sprite.new(620, 0, Image.new(20, 480, C_WHITE)),
         bar]

ball = Sprite.new(300, 400, Image.new(20,20).circle_fill(10,10,10,C_WHITE))
dx = 4
dy = -4

image = Image.new(58, 18, C_WHITE)
blocks = []
5.times do |y|
  10.times do |x|
    blocks.push(Sprite.new(21 + x * 60, 21 + y * 20, image))
  end
end

Window.loop do
  bar.x = Input.mouse_pos_x
  Sprite.draw(walls)

  ball.x += dx

  if ball === walls
    ball.x -= dx
    dx = -dx
  end

  ary = ball.check(blocks)
  if !ary.empty?
    ary[0].vanish
    ball.x -= dx
    dx = -dx
  end

  ball.y += dy

  if ball === walls
    ball.y -= dy
    dy = -dy
  end

  ary = ball.check(blocks)
  if !ary.empty?
    ary[0].vanish
    ball.y -= dy
    dy = -dy
  end

  ball.draw
  Sprite.draw(blocks)
end