技術部第3グループの廣江(@buta_botti)です。会社のサポートを受けてRubyKaigi2022に参加させていただきましたので、自分の見聞きした範囲で簡単に紹介させていただきます。内部の難しい話はわからないので、その辺りに興味のある方には他の方の参考になるレポートや、発表者の方のスライドやブログを参考にしていただくとして、今回は利用する側の目線で色々書ければなと思っています。
タイトルはこちらのスケジュールに記載のものを流用しています。
Ruby meets WebAssembly
ざっくりと言うとRubyがブラウザ上で動くようになりました。多少の課題は残っているものの、多くのRubyスクリプトには影響がないので、どんどん利用してフィードバックしていくことが私のような一般Rubyistが貢献できる方法となります。
利用方法は至って簡単です。
<script src="https://cdn.jsdelivr.net/npm/ruby-head-wasm-wasi@0.3.0-2022-09-06-f/dist/browser.script.iife.js"></script> <script type="text/ruby"> # Ruby code </script>
<script type="text/ruby">
内に書いたRubyコードが実行され、p
メソッドやputs
メソッドを使うとコンソールに出力されます。
少し凝ったことをしようとすると、JavaScriptで多少ゴニョゴニョする必要があります。
<script src="https://cdn.jsdelivr.net/npm/ruby-head-wasm-wasi@latest/dist/browser.umd.js"></script> <script> const { DefaultRubyVM } = window["ruby-wasm-wasi"]; const main = async () => { const response = await fetch("https://cdn.jsdelivr.net/npm/ruby-head-wasm-wasi@latest/dist/ruby.wasm"); const buffer = await response.arrayBuffer(); const _module = await WebAssembly.compile(buffer); const { vm } = await DefaultRubyVM(_module); vm.eval("# Ruby code"); } </script>
凝ったことをするにあたって、RubyからJavaScriptを実行したいこともあるでしょう。その場合はrequire 'js'
でJSライブラリを使えるようにします。
<script> // ...省略 vm.eval(` require 'js' text = "Hello Ruby!" JS.eval("document.body.innerText = '#{text}'") `) </script>
HTML上のbodyに「Hello Ruby!」を表示できます。
ここで紹介したようなサンプルは、全てruby.wasmで詳しく書かれています。とても親切。
また、require 'js'
したJSライブラリの実体は以下のファイルのようです。
C言語が読めなくても、親切なコメントが書かれているため、使い方を理解することができます。
Types teaches success, what will we do?
こちらは gem_rbs_collection の紹介になります。
実際にプルリクを出して取り込まれるまでの過程を丁寧に解説してくださっており、自分もやってみようという気にさせていただけました。内容としては docs/CONTRIBUTING.md の内容を日本語で詳しく解説していただきました(スライドは英語)。
自分のプロダクトで使っているケースで型を書けばよいということらしく、そのライブラリが想定しているすべてのパターンを考慮しなくても気軽にPRを出せるのということなので、すごく取り組みやすいのではないでしょうか?個人的にはOSS活動の中でも(ライブラリの理解は使っている以上前提として)typo探しの次くらいに取り組みやすい領域だと思います。早速手元のRailsプロダクトでsteep checkして、不足している型をgem_rbs_collectionに提出しましょう!
Tools for Providing rich user experience in debugger
www.slideshare.net
(VS Codeを利用していない方でも)ChromeのDevToolsでめちゃくちゃ好体験のデバッグができるようになったという話でした。
利用しているRubyにdebug.gemがインストールされていることが前提です。
$ rdbg --open=chrome sample.rb
もしくはプログラム内のdebugger
で開くrdbgコンソール上で
open chrome
でデバッグ用のChromeDevToolsを開くことができます。
Sourcesタブでデバッグ対象のRubyプログラムが確認でき、ConsoleタブでRubyスクリプトを実行できるみたいです。これだけでもテンションが上がりますね。Consoleタブで実行したRubyプログラムはSourcesタブのプログラムの状態に影響するようです。
↑変数a
の値が書き変わっている様子
Make RuboCop super fast
RuboCopはrequire 'rubocop'
の処理が重いという課題があったそうなのですが、この度サーバーモードというのが追加されたことによって、RuboCopサーバーをローカルに立て、そこにRuboCopモジュールをロードしておき、RuboCopの実行をこのサーバー上で行うことで重いrequire
処理をスキップ(正確にはrubocop/server
という軽量なものだけで済む)でき、高速化します。
RuboCopサーバーが起動していない状態でのデフォルトのrubocop
コマンドは従来通りの動きで、オプションを明記したrubocop --no-server
と同等です。rubocop --server
でRuboCopサーバーが起動していない場合に起動し、サーバーモードでRuboCopを実行し、サーバーの停止、再起動はそれぞれ--server-stop
と--server-restart
が対応しています。起動しているサーバーのステータスは--server-status
で確認できます。
ちなみに、RuboCopサーバーが起動している状態でオプションなしの rubocop
コマンドを実行すると、サーバーモードになるそうです。
error_highlight: user-friendly error diagnostics
(スライド見当たらず...)
エラー表示がとても親切になりました。実際どう便利なの?今でもファイル名と行数出てるから場所わかるし十分では?みたいな意見に対しては明確に便利になるケースを提示してくださっていました。
例えばerror.rbの2行目に次のコードがあります。
hash[:foo][:bar][:baz]
ここでNoMethodErrorが起きた場合のエラー表示は以下のようになります。
error.rb:2:in `<main>': undefined method `[]' for nil:NilClass (NoMethodError)
何番目の[]
が原因か分かりにくいですね。これがerror_highlightによって
error.rb:2:in `<main>': undefined method `[]' for nil:NilClass (NoMethodError) hash[:foo][:bar][:baz] ^^^^^^
のようになります。原因箇所が一発でわかって便利です。
また、実際のコードがチラッと見えることによって、見覚えのあるコードであればおおよそのあたりをつけてデバッグを開始できたりと、デバッグにおいてかなり便利になるのではないかなと思います。
Real World Applications with the Ruby Fiber Scheduler
Falconやasync.gemが出てきてPumaよりFalconの方がパフォーマンスが出ていたというのはスライドを見ていて分かったのですが、なにぶん英語が聞き取れなくて後でスライド見ようと諦めて聞き入っていたのに、いざまとめようとするとスライドも見つけられなくてめちゃくちゃ悲しい思いをしています。他力本願すぎたことを戒めに英語を勉強しなければなという気持ちにさせられました。スライドを眺めていただけのイメージで話をすると、今のアプリケーションは大量のリクエストを捌ききれないことがあり、それがノンブロッキングなFiberを使うことで捌けるようになってパフォーマンスも上がるみたいな感じなのかなと思っています...。FalconをRailsで使うとActiveRecordのリクエストをFiberで捌けるようになるとかそんな内容もあったとか。実際はそんなサラッとした内容ではなくて実現するための苦労話がたくさんあったと思います。
github.com github.com github.com
Rack3でストリーミングに対応するという話も出てたみたいですが、この辺りのことのなのかな...?
There is one new feature in Rack 3 which is not directly backwards compatible:
・Response body can now respond to #call (streaming body) instead of #each (enumerable body), for the equivalent of response hijacking in previous versions.
ここのリポジトリに情報が詰まってそうなので、読んだり動かしたりした後にまたブログを書ければなと思っています。 github.com
History of Japanese Ruby reference manual, and future
るりまの話を聞きました。個人的にはるりまをRDocからMarkdownで書けるように...や、サンプルコードをwasmで動かせるように...と計画しているのが一番インパクトがありました。Markdownなら普段から使っているので、ちょっとドキュメントの修正をしたい時に簡単に提案ができていいなと思いますし、サンプルコードをブラウザ上で実行できるのもすごく手軽に動作を確認できていいですね!るりまは新しく追加された機能とかについては割と大丈夫だけど、昔からある機能については更新されてなかったりとかするみたいなので、その辺りにコントリビュートチャンスがありそうな気配がします。ひっそりとissueを出しても埋もれてしまうので、ruby-jpのslackなどで相談しながら進めていくのがいいのかなと思います。
多言語対応もロングスパンで進めていくそうで、日本語以外を母国語に持ち、翻訳をしてくれる方を募集しているそうです。
あとはissueが山盛り溜まっているっぽくて、現在のステータス管理とかしてくれる人を募集中だそうです。Ruby本体の方でも似たような話を聞いたような...?
るりまには長年お世話になっているので、何らかの形で恩返しをしていきます。
全体の感想
TwitterやSlack、Discordで普段話している人とオフラインで会うことができてとても楽しい3日間を過ごすことができました。発表に関してはやや難しくて理解しきれない部分も多くありましたが、そこは実際に触ってみて、体で覚える方向でカバーしていきます。実際にデモを用意して動かしてみる記事も別で書いていますのでお楽しみに!RubyKaigiは美味しいご飯とお酒を飲みながら、知り合いと好きなプログラミング言語についてわいわいと語らうことができるので最高ですね。今回、現地参加は弊社からは私一人でしたが、私と一緒にRubyKaigiに行きたい!という方が社内に増えてくれるととても嬉しいなと思っています。