平成Ruby会議01 に参加してきました #heiseirubykaigi

めちゃくちゃ楽しかったです。

トーク感想

What is expected?

かねこさんのキーノート。パーザーの話。トーク前に expectってかいときゃ rspec だと思われるでしょ、などと邪悪な発言をしており治安が悪いなと思いました。

僕はスライドのチェックを依頼されたので事前に資料だけは見ていたのですが、なかなか骨太な内容でしたね。state の遷移図が結構くせもので、あれがあると state 自体が変化していくように思っちゃうのですが、実際には state の stack になっているのがミソです。あの図がないと遷移のイメージがわかない一方で、あれがあると誤解しやすいという。

まあたぶん誰も質問しない(できない)だろうと思って質問したいなーと思っていたのですが、なにせスライドを事前に読んでわからないところを聞いてるから質問が思い浮かばない。これはマズいと思っていたところ、資料チェック時には読み飛ばしていた(すみません)実装の話で、default reduce を使わないという方針はないのかという質問をしました。

そもそも、default reduce を使うというのは action table のサイズが小さくなるのが嬉しい一方で、エラー発生が遅延する(とりあえず reduce してから行きづまるため)ことと stack への依存が強くなることが一般的な問題点として挙げられていました。action table のサイズは、ruby バイナリ自体のサイズ及び実行時のメモリフットプリントに影響する気がします。まあ昨今のストレージおよびメモリは潤沢にあるとされているので、ある程度の増加なら特に問題ないような気もします1。というわけで一般的な問題は解決できるものとすると、問題は parse.y が default reduce 中に LEX_STATE を書き換えているところだけになるので、そっちの選択肢はないのかなあ、というのが質問の背景でした。まあ結論からするとほぼ全面書き直しになるのでは?という話で無理だったわけですが。

そういえば compress するときに default 挙動をまとめたからって、最終的に本当にエラーになるかってあんまり自明じゃなくないですか?どうなってるんでしょうね。行き詰まらない場合には default 挙動ではなくちゃんとエラーにしてるのかな。

Ruby2.7以降のiseqのバイナリ表現の改善について、Rubyアソシエーション開発助成金2019採択プロジェクトの途中経過について

ISeq のバイナリ表現を改善したよっていう話。たぶん最初はバイトサイズも小さく、読み込むまでの時間もはやくなるようにしようとしたんだけど、実行時間まではそんなに早くならなかったのではないかと邪推している。

資料的には具体例が3つあったけど話せたのは2つまで。不要な情報の削除、数値表現の圧縮。圧縮のほうは msgpack か?というツッコミがあったけど utf8 とかを参考にしたと言ってたみたい。戦略的には短く表現できるものをより短く表現するために余分な情報を先に付与することで、長くなるのを防ぐって感じっぽい。

バイナリサイズが小さくなると何が嬉しいのか、というと開発環境的にはまあ当然嬉しいものとして、Railsアプリを本番で動かすシーンで嬉しいのか、という話はある。立ち上げ時の時間を気にするようなサービスがあったときに Docker イメージ内に bootsnap cache もいれておく、みたいなことすることあるんですかね?あるならそこの転送量が減ってうれしそう。bootsnap を真面目につかったことないのでこのへんどうなのかなーと気になるところ。

SimpleDelegator活用のご提案

draper とかの decorator ってこれ由来なんだろうなーと思わせるなにか。局所的に拡張したいみたいなことはあるので、ありな気がする。例えば特定のコントローラー内の inner class としてしまうとかね。似たようなのフルスクで書いてたけど SimpleDelegator 使えばよかったな。

Ruby on Jeeeeeeeeets!!✨🚀✨

ジェット機Ruby が組み込まれてるんですか!?っておもったら違った(思ってません)。サーバーレスフレームワーク jets の紹介。サーバーレスなんもわかんねーって思いながら話を聞いてました。アクション単位でラムダ分割するのは面白いなと思った。既存 Rails アプリを分割するの、絶対ムリだろ感があるのにチャレンジしてるのは胸がアツい。

アセット関連のところで「アイツですよアイツ」って言われて Sprockets かなって思ったら Webpacker で、そうだねって思いました。

休憩

疲れたんで広いスペースでぼーっと

既存RailsApplicationの高速化

Rails アプリを高速化するようなやつつくりてー、って話(つくれたとはいってない)。

マジで実行して評価する系のアプローチは、評価するパスを通す必要があるのでめんどいってのと、本人も言っていたようにそのメソッドの返り値をうんたらかんたら、みたいなことをすると解析のスコープがでかくなってめんどい(実質無理なのでは?)という問題があります。コード解析はそういう意味で返り値がどう使われているのかなどはレキシカルなスコープでは非常にわかりやすいので今回のケースだとそちらのほうがよさそうに見えました。

一応評価するときのアプローチでも、例えば count で Integer を返すのではなく IntegerWrapper を返して #zero? を呼ばれたら警告を出すみたいな、ほぼ Integer と同じなんだけどときどき警告を出すみたいなナニカを返す方法はありそうです。質問でいうにはデカい話になるので省略しましたが。これは後に pocke さんと話したときに「それだと if を騙せない」という話になり学びがありました。Ruby の if は nil と false をチェックするCの実装があり( RB_TEST でしたっけ)それを騙すことが Ruby のレベルでは(たぶん)できません。たぶんこれを騙すには maccro とか使ってやる必要がありそう。 ifif _if とかに書き換えるやつです。あと if じゃなくてパターンマッチなら deconstruct とかで挙動を上書きできるから悪いことできそう。

あとまあ個人的な感覚では、世にある Rails アプリケーションは DB と非常に密接に関わっているので DB レイヤへの言及なしに速度の話をするのはあまり本質的でないのでは、と思っています。

RubyJVMを実装してみる

JVM の話。step by step で進んでいきよかった。JVM実装流行してますね。

time ではかったときに system が増えているのは IO#read のせいではないんじゃないかなーと思っています。IO#read は buffered なはずなのでカーネルレベルでのオーバーヘッドがかかるわけではない、と思う。単純に ruby バイナリを起動してからスクリプトを読むような時間が必要なのでそことかじゃないですかね。勘ですが。まあそもそも ruby バイナリの起動にどんくらいかかってるのかも知らないけど。

System.out.println の実装は結局どうしたのかが気になってます。中で Rubyputs してるのか、そのへんのライブラリも読めるのか、読む必要がないのかなど。懇親会で聞こうかなと思ってたんだけど行けなかったので残念。

Good to know YAML

この問題設定みたことあるーって思いながら聞いてました。妥当なアプローチがすすんでおりよさそうでした。

@enable_validator 的なのがあるのはたぶん今後の展望に関係してるんだろうけど今のところなんで存在してるのか謎だね、という感じがあり、そのへんを質問したかった。時間がなかったので終わった後お話させてもらいました。

rustで拡張モジュールを作成してgemにする

おもしろかった。コンパイルどうすんのかな、fat gem なのかなと思っていたらthermite なんてあるんですね。GCCとかと違って普通にあるわけじゃないから大変そう。

今回は Symbol#start_with? の実装の話だったんだけど、これオブジェクトのアロケーションとかをするとなんか大変そうだなーと思った。cruby からもらったメモリはまあ触らなければよくて、Rustでアロケーションしたやつをどうするのかとかが気になる。でもC拡張でやってるのと同じようにすればなんとかなりそうな気もする。

階層的クラスタリングRubyで表現する

階層的クラスタリングってなんや〜と思って聞いてた。解析してみても特に面白い結果がでないというのはまあよくある話で(俺もやったことある)つらいですね。前処理のレベルでどうなるのかわからんけど難しそうだった。自然言語処理なにもわからない……。

Play with Ruby

parse.y を操作するライブコーディング。アツい。ujm さんのトーク を思い出しますね。右代入の実装でした。

最初コンフリクトしないような気がしていたけど p { a => b} が Hash を引数にとるのか、右代入のブロック引数なのかで解釈がわかれますね。あのコードでどっちが勝つのかは謎。

openssl のエラーは configure でフラグ渡せば解決します。あるいは miniruby をビルドするだけでも動きそうなのでそこで止めてもよさそう。具体的にはこうしておくとよい、というのを昔教えてもらったのでおいておきます。brew --prefix とか使ったほうがたぶんきれい。

gist.github.com

休憩

夜の街を散歩してました

LT

knu さんの。自身の経験から若者を導く感じがあってよかった。

tadsan の。まさにLTっぽい勢いでよかった。

すみません忘れちゃった&HPにないからよくわからない。成果発表って感じだった。俺もなんかやらんとなーという気持ちになりました……。

Breaking Change

koic さんのキーノート。これも自分がやっていることをもとに話しており、koic さんにしかできない話でしたね。内容的にも非常に教育的で僕も聞いててうなずくシーンが多かったです。某 issue はほんとになんにもよくなくてワロタ

高機能書き換えツールとしての rubocop ってのは考えたことなかったけどいい手法だなと思いました。俺もちょっと素振りしとこ。

運営とか

あと運営の人宛の思ったことをちょっと書いときます。

  • 2トラックやるときにスマホで2トラックがひと目で見れないと判断に迷うので、そういうデザインになってると助かりました
  • トーク内容の説明がないと判断ができないので詳細ページがあるとよかったなと思いました

全体的に非常に楽しかったです。骨太なトークが多く満足感がありました。
スピーカー、スタッフのみなさんありがとうございました。


  1. 雑試算したら30MBとかあったのでちょっとウッとなりましたが