STORES Product Blog

こだわりを持ったお商売を支える「STORES」のテクノロジー部門のメンバーによるブログです。

Rubyでフロントエンドを書く未来、おもしろRuby in the browser事案。深掘りRubyKaigi 2024 文字起こしレポート vol.2

2024年6月20日に『深掘りRubyKaigi 2024 with kateinoigakukun & ledsun & remore』を開催しました。イベントの内容をほぼ全文文字起こし形式でお届けします。この記事は第2部です。

hey.connpass.com

イベントのアーカイブはYouTubeでも公開しています。

登場人物

ゲスト

  • kateinoigakukun/齋藤さん
  • ledsun/中島さん
  • remore/澤田さん

STORES

  • fujimura/藤村 大介
  • mame/遠藤 侑介

ブラウザでRubyを動かすことに興味を持ってくれるといいな

fujimura:次はledsunさんにお話を伺おうと思います。よろしくお願いします。まずはちょっとした個人史的なものをお聞きしたいと思います。プログラミングやRuby、フロントエンド開発について、どのくらい前から始められたのか教えていただけますか?

ledsun:プログラミングに最初に触れたのは中学生の頃で、家にMSXというコンピュータがありました。当時は雑誌にプログラムが印刷されてついてくる時代で、それを手入力して主にゲームを動かしていました。これがプログラミングの最初の経験です。本格的にプログラミングを始めたのは就職して仕事になってからで、2003年頃です。ですので、ちゃんとやっているのは約20年になります。

Rubyに初めて触れたのは2006年頃です。当時は主にJavaを使っていましたが、時々勉強する程度でした。本格的に使い始めたのは2018年頃で、約5年前から仕事でも使うようになって、主にRuby on Railsを使ったアプリケーション開発を行っています。その頃からRubyKaigiにも参加するようになりました。たしか仙台だったと思います。

フロントエンド開発はもう少し前の2010年頃から始めていて、JavaScriptを使ったウェブアプリケーションを開発していました。その頃はNode.jsが流行り始めて、フロントエンドのツールもGruntからBabelやWebpackへと変わっていった時期でした。その頃だったので、フロントエンド開発が変わっていくのを体験してました。

fujimura:僕も同じ時期にフロントエンド開発をしていたので、混戦模様がすごかったですよね。ビルドツールが2年ごとに入れ替わるみたいな。

ledsun:そうですね、GruntからGulpに移行したと思ったら、Gulpも使えなくなって早いなぁって。そういう世界でしたね。

fujimura:では、改めて今回の発表の内容をざっくりと教えていただけますか?

ledsun:発表は前後半に分かれていて、前半では、ruby.wasmに対して私がどのような取り組みを行ったかについてお話ししました。ブラウザ上でRubyを使う時に足りないものを足した話をしました。例えば、require_relativeをブラウザ上で動かせるようにしたみたいな話ですね。

後半では、ブラウザ上でRubyを書くことのメリットを見せたくて、今回自分で作成したフレームワークを紹介しました。アプリケーションはイメージしやすいかもしれませんが、フレームワークのアイデアはまだないかなと思ったので、これでみんながブラウザでRubyを動かすことに興味を持ってくれるといいなと思って、そういう発表しました。

rubykaigi.org

fujimura:フレームワークのAPIがRailsを書いている人には馴染みが深い感じになっているのが面白いと思ったのですが、狙いがあったんですか?

ledsun:そうですね、フロントエンドのフレームワークと言うと、Reactみたいなのを考えますが、Rubyの人には馴染みにくいだろうと思って。Railsに近い方がインパクトがあるだろうと考えたので、狙ってやりましたね。

Rubyでフロントエンドを書く未来

fujimura:そもそもWasmに興味を持ったきっかけや触り始めた時期はいつだったんですか?

ledsun:Wasmに触り始めたのは2022年、kateiさんの発表でruby.wasmを知って、ブラウザでRubyが動くことに興味を持ちました。まずはHello Worldを動かしてみたのですが、スクリプトタグの中に直接書けるものの、src属性を使って外部ファイルを読み込めないことに気づきました。ソースコードを確認したら、スクリプトタグの中からRubyスクリプトを実行するのは比較的簡単そうだったので、これをsrcタグでもできそうだなってプルリクエストを出したのが最初です。

fujimura:バリバリのKaigiEffectですね。

ledsun:そうですね。

fujimura:Rubyでフロントエンドを書くという未来について、構想も含めていろいろお話ししたかったのですが、まずはど真ん中についてお伺いします。現状では、少なくとも一部のフロントエンドはRubyで書けるようになっていますが、本当に何でもRubyでフロントエンドを書けるようになった場合、どのような体験になってほしいですか?どういうことしたいですか?

ledsun:僕の中では、だいぶ何でも書けるので。今やりたいと思っているのは、ブラウザからdRubyを使ってサーバのメソッドを呼びたい。サーバ側にはdRubyサーバがあり、ブラウザからWebSocketなどを使ってリモートプロシージャーコールができたら面白そうだと思っています。

fujimura:昔のフロントエンドエンジニアが夢見ていたIsomorphic JavaScriptの概念に近いものですか?

ledsun:通信も含めてRubyになるので、もっと近い感じになるかなと思います。

fujimura:遠藤さんが「おー」って言ってましたけど。

mame:20年ぐらい前に分散オブジェクトというのがあったのが、ついに現代にやってくるのかと感動してました。ERBもフロントエンド側で使ってますよね?kateiさんとruby.wasmの応用例を考えていたときに、ブラウザのフロントエンドのエンジニアリングをruby.wasmでやるアイディアもあったんですね。それを実際に実現していただいたので、私も「おー」と思いました。そこからdRubyにも応用するとすごいなって。

fujimura:普段のお仕事ではRubyでバックエンドを書いているのでしょうか?フロントエンドも書いてるんですか?

ledsun:仕事としては、マネージャー業務が半分、プログラマとしての業務が半分という感じです。プログラマとしては主にライフサイエンス統合データベースセンターという組織があって、そこが作っているPubAnnotationというウェブアプリケーションがあって、そのバックエンドはRubyで、10年ぐらい関わっています。Rubyもやってるし、JavaScriptもやってるという環境です。

fujimura:例えば、プロダクション環境でフロントエンドもRubyで書こうとした場合、何が障壁になりそうですか?

ledsun:とりあえずエンジニアが少ない。私が書いて動かしても他の人がメンテナンスできないと今のところはなってしまう。それでもやりたいっていう何かしらのキラーフィーチャーがないと、押し通せないなって思っています。

fujimura:フロントエンドでは最初にインタラクティブになるまでの速度が重要だと言われていると思うんですけど、今のruby.wasmでやるとゆったりした感じになるんですよね。そこも課題になると思ったんですけど、業務アプリケーションだと関係ないですかね。

ledsun:業務アプリケーションだったら別にいいのでは。例えばMiroって起動まで結構待つじゃないですか。パッと開かないでちょっと待つ感じがあるんで、ああいう感じの仕事で使うツールで意外とみんな待ってくれるんじゃないかなって。C向けやメディアは速度が求められると思うんですが、業務系はいけるんじゃないかな。特にエディタみたいなめんどくさいやつは(ユーザーが)起動するのに時間がかかるだろうと思ってくれるので、いいんじゃないかなって思います。

kateinoigakukun:アプリケーションのコードってそんなにネックじゃなくて、一番重いのはインタープリタの部分ですね。それって毎回ダウンロードする必要はないとか、いろいろ考えると最初の1回目のロードが超遅いけど、例えばAppストアからアプリをダウンロードするのと比べれば、許容範囲かなくらいになると思うんですけど、どうですかね。

ledsun:それはその通りで、例えばソーシャルゲームって頑張ってみんなデータダウンロードするじゃないですか。あれに比べれば全然早いので。面白ければみんな使ってくれると思うんですよね。

fujimura:複雑なGUIとかのプログラムを簡単に書けて、サーバサイドとの差分もない、同じように書けてめちゃ便利でいいものができるんだったら、多少の待ち時間は許容されそうですよね。

ledsun:そうですね。

おもしろRuby in the browser事案

fujimura:RubyKaigi後に発見されたおもしろRuby in the browser事案があれば聞いてみたいなと思ってました。

ledsun:yancyaさんに教えてもらったんですが、yancyaさんはRubyKaigiでyancyaハウスっていうRubyistで集まって、AirBnBとかで借りた宿で過ごしてるんですね。それを募集するサイトを作ってるんですけど、そこでruby.wasmを使ってると教えてもらいました。 何に使ってるかっていうと「今何人が見てます」っていうメッセージを出している部分なんですね。どうやってサーバと通信してるんだろうと思ったら、ジョークプログラムでランダムに数値が出てるんですね。

一同:(笑)

ledsun:なのでプログラムとしてはめちゃくちゃ短くて簡単なんですね。Rubyだとそういうのが本当に簡単に書けるじゃないですか。これはいいなって思いました。

fujimura:ふざけやすいっていう楽しいところがあるかもしれないですね。他にもありますか?

ledsun:今度は富田さんに教えてもらったやつで、Rubyのmain.rb、入口をディレクトリの中に置きたいけど、それだとrequire_relativeが動かないと教えてもらったんです。それは僕の中では全く思いつかなかったユースケースで、話を聞いて(はじめて)「ディレクトリの中に入れたいよな」って思ったので、そういう使い方があるっていうのはちょっと面白かったですね。

fujimura:違うところに置きたいってことですね。

ledsun:僕は完全にWebサイトのルートディレクトリにmain.rbを置くって勝手に思ってたので、違うところに置くことが新鮮だったんです。

kateinoigakukun:サブディレクトリに入ったところから、さらに上に上がってrequire_relativeするっていうのができないっていう話ですか?

ledsun:今のrequire_relativeってHTMLのルートから取っちゃうんですよ。HTMLから相対パスを取っちゃうんで、index.htmlからlib/main.rbを読んじゃうと、パスが一段ずれちゃうんですね。

kateinoigakukun:なるほど。

fujimura:直せそうだけど、どの直し方でも悩ましい感じになりそう?どうなんだろう。

ledsun:ベースURLに使いたいところを教えてあげれば、多分動くはずとは思ってます。ちょっと作ってみたんですけど、今のところうまく動いてないので、普通に動くはずなんだけどなと思ったけど、意外と難しくてちょっと苦戦してます。

ruby.wasmへの要望

fujimura:あとはRuby in the browserをしていて、できるかできないかわからないけど、ruby.wasmにはこうなっていてほしかった、これが欲しかったみたいなことってありますか?

ledsun:本当にRuby全体が動くので、制約とかない。ネットワークが使えないとか、I/Oが使えないとかはあるけど、それはそうなので。Rubyの機能として使えないものはないので、特にないんですよね。

kateinoigakukun:本当ですか?

fujimura:全部知ってる人たちから見たらそうかもしれないですけど。

mame:ruby.wasmを使うのに、ちょっとハマりません?特に初期はデバッグが辛かったところは正直ありますね。JavaScriptコンソールの中にエラーメッセージのバックトレースが出てくる。Rubyのデバッグはあれがあるだけで大丈夫ですか?

kateinoigakukun:一筆書きでいける?

ledsun:いや、もちろんデバッグするんですけど、JavaScriptのデバッグもだいたいプリントデバッグなので、そんなに途中で止めたいとかがない。止められたら便利だと思いますが。

mame:普段のRubyはどうやってデバッグされてます?binding.irbとか使ってます?

ledsun:pを一番使ってますね。

mame:僕もそうなんですけれども、それだけでいけますか?

fujimura:ちなみに僕はruby.wasmで動かす前にPure Rubyで動かすようにして、アダプター的にruby.wasmで動くように切り替えて、結局Pure Rubyで書いたほうでデバッグしてましたね。

ledsun:僕も割とRubyで書いたものをブラウザに持っていって動かすことをしています。例えばIRBでRubyのコードを動かして、このアルゴリズムで普通に動くかを確認してから持っていくことが多いです。なので、デバッグでハマるっていうのはあまりしてなかったかもしれないですね。

mame:でも、今回作られたのってフロントエンドフレームワークじゃないですか?フロントエンドフレームワークってPure Rubyで動かせないですよね?

ledsun:ああ、確かに。

mame:だから大変そうなところをやってるなと思ってました。

ledsun:動かしててRubyで動いてないのか、JavaScriptで動いてないのかがよく分からなくなっちゃうっていうのはよくあります。どっちが原因で動いてないのかを自分の頭の中でうまく整理できなくなる瞬間はあります。

mame:なるほど。

fujimura:ruby.wasmの中でJavaScriptをいっぱい書かないといけないこともありますよね。あの時とかデバッグが大変だなって思いました。

ledsun:そうですね、確かにPromiseとかがうまく動かなかった時とかは辛いです。

fujimura:でもRubyもフロントエンドも両方やっていると、それぞれで解決すればいいやとなって、あんまり引っかからないかもしれないですね。

ledsun:JavaScriptの方はそんなに困らないというか、JavaScript的にこれがダメなんだっていうのはわかるので、そこは困ってないかもしれないですね。

GitHub Copilotはruby.wasm中級者みたいなコードを書く

fujimura:ちょっと質問をいただいているので、読み上げてみようと思います。

JS側のオブジェクトをruby.wasmから操作するときに、呼び出し方 (hoge[:fuga] か hoge.fuga) を区別する必要があって頻繁に実装ミスしています。その辺がRubyistに優しく(甘く)なるとめちゃ嬉しいですね…!

kateinoigakukun:それについては、だいぶ初期から要望をいただいていて、なぜこういう分け方になっているかというと、Rubyのメソッド呼び出しとプロパティアクセスが区別できないんです。例えばドットでプロパティアクセスしていると思っていても、実は下側ではJavaScriptのメソッドを呼び出している形になると、どうなんだろうなと思って。そこでシンタックスシュガーを入れる前にシンプルなインターフェースにしておいて、後からそこはどうにでも拡張できるので、余地を残している状況なんです。できない理由はなくて、僕の好みなんですけど、それですごく困っている人がいるのであれば検討の余地はあります。実際にそこの区別の仕方で困りますか?

ledsun:書く方としては慣れの問題なので困らなくて、混ざると困るっていうのはあって、あるかないか分かんないプロパティを呼んだ時ですね。JavaScriptだとundefinedが返ってくるんですけど、それがどうなってほしいのか。それがタイプミスしてて、呼びたいメソッドが呼べてないのか、それとも本当にないものを呼んでるのか。JavaScriptでたまにundefinedであることを確認したい時があって、プロパティに設定されてないのを知りたいことがあるんですね。その時にメソッドが合ってるのか間違ってるのか、よく分からなくなっちゃうんですよね。メソッド呼び出しか、プロパティ呼び出しかを考えて、かつ、それがJavaScript的に正しい名前かを2段階考えるのが辛いんです。なので、呼ぶ時に自分としては「これはプロパティを呼んでる」「これはメソッドを呼んでる」って分けて書けた方が嬉しいのは嬉しいです。

kateinoigakukun:なるほど。

mame:GitHub Copilot使ってます?

ledsun:使ってます。

mame:ruby.wasmのJavaScriptのインテグレーションのコードをびっくりするくらい正確に補完してくるんですよ。世の中にほとんどruby.wasmのコード例はないだろうに、今言った「プロパティを呼び出すのか、関数を呼び出すのか」を結構な高確率で当ててくるのでびっくりするんですよね。

fujimura:ruby.wasm中級者みたいなコードが出てきますよね。

mame:プロパティは obj[:property] で呼び出すってことを知っているのかってくらいの精度で出してくるので驚きました。あれのおかげで自分のミスに気づけたこともあるくらいです。Copilotを使うと割と楽でした。

kateinoigakukun:便利。

ledsun:あれは不思議ですよね。絶対世の中にそんなコードがあるはずないのに、どこから学習したんだって気持ちになりますね。

fujimura:未来から来たのかな。

mame:Copilotを使うと、JavaScriptのaddEventListenerとか書いても、ruby.wasmスタイルのブロック記法で出してくるので、びっくりします。

ledsun:あれは不思議です。

kateinoigakukun:みなさんにruby.wasmを書いていただけると、もっと賢くなるでしょう。

fujimura:もう一つ質問があります。

ruby.wasm 上でベンチマークツールは動きますでしょうか?

kateinoigakukun:Rubyインタープリター上で動かすような、例えば、require 'benchmark'とかは、Ruby上で動くんで動きます。ベンチマークツールってどういうのを想定しているんだろう?

benchmark-driverとか

mame:k0kubunさんが作ったベンチマークを動かすためのgemですね。ベンチマークを書いたり、Rubyのコード断片を持つYAMLで読み込んで実行するものの話をしているような気がします。

kateinoigakukun:どうですか、動きそうですか?

mame:正直わからないです。さっき標準ライブラリのベンチマークだったら、多分動くって言ってたけど、動きますかね。sysとかrealとかあるじゃないですか。システム依存のタイミングを見るやつが、動くのかなってのはちょっと分からなかった。user、sysとreal。

kateinoigakukun:そこ見てますか?

mame:見てませんでしたっけ。

kateinoigakukun:clock_gettimeのWallClock見てるだけじゃないんですか?

mame:userとsystemとrealの3つのカラムが出るやつじゃないかって言ってたっけ。それぞれが取れるのかなってのはよく分かんないけど。

kateinoigakukun:取れるんじゃないですか。少なくともCLOCK_REALTIMEとCLOCK_MONOTONICがあるんで、いけそうな気がする。

mame:動かなかったらプルリクエストを送っていただいて、そんなに難しくないと思うけど。

kateinoigakukun:お願いします。

fujimura:遠藤さんから質問ありますか?

mame:一番聞きたかったのは、ruby.wasmでハマらないですか?ってことだったので。ハマらないとさっき聞いたので。

kateinoigakukun:遠藤さん散々ハマってるから。

mame:びっくりするくらいruby.wasmでハマるんですよね。すぐSEGVするんで。

kateinoigakukun:さんざん壊していただいて。

mame:ついこの間もIRBを動かそうとして、segfaultしてたのをkateiさんに直してもらいました。ありがとうございます。

kateinoigakukun:Mastodonが動くのにIRBを真面目に動かそうとするとsegfaultするんですよ。びっくりですよね。

fujimura:何が起こっているのか。他のお二人および隣接分野とか、そうじゃないところも含めて、RubyKaigiの感想を教えてください。

ledsun:kateiさんに関しては先ほど言ったサイズを小さくするロードマップが熱かったですね。remoreさんは発表の後でお話も聞いたんですけど、簡単なプログラムが簡単に動くってすごくいいなと思ってて。そういうのがエッジコンピュータでも動かせたらいいなって思いました。

fujimura:そうですね。そろそろledsunさんのパートを終わりにしようと思います。ありがとうございます。

第3部に続きます。

深堀りRubyKaigi 2024 文字起こしレポート一覧