
2025.08.01
災害大国・日本に求められる“命しか守れない防災”からの脱却 最長2週間先の気象災害予測による対応策
リンクをコピー
記事をブックマーク
齋藤優太氏(以下、齋藤):いやぁ~、緊張しますね(笑)。みなさんおはようございます。
会場:おはようございます。
齋藤:「Ruby meets WebAssembly」ということで、今日は最近少し話題になっているRubyとWebAssemblyの話をしようと思います。よろしくお願いします。
(会場拍手)
RubyがWebAssembly上で動くようになったので、今日の話はその紹介になります。何事もなければRuby3.2の機能として出荷される予定です。今日は始めに、なぜWebAssembly対応をするのかというモチベーションを紹介して、RubyのWasm対応デモを交えながらWebAssemblyのユースケースについて紹介します。後半は、Wasm対応にあたってどのようなことをしたのかという具体的な技術的な内容になると思います。
あらためまして、Rubyのコミュニティでは初めましての方が多いと思うので、少しだけ自己紹介をさせてください。齋藤といいます。インターネットでは「kateinoigakukun」というハンドルネームで活動しています。本業は早稲田大学の学生なのですが、GoodNotesというノートアプリの会社で、ソフトウェアエンジニアとしても働いています。
Rubyとの関わり方としては、2021年のKeynoteで、遠藤さん(Yusuke Endoh氏)が紹介されていたTypeProf for IDEのお手伝いをクックパッドのインターンとしたり、秋頃からは、CRubyのWebAssembly対応の作業をやっています。その流れで2022年の頭からは、CRubyのコミッターとしてWasmポートのメンテナーをしています。
SwiftでもコミッターとしてWebAssembly対応をやっていたり、Link-time-optimizationの実装や、コンパイラからインタプリタまでいろいろとやっています。
さっそくですが、内容に入っていきましょう。始めに、モチベーションですね。RubyとSwiftって何から何まで違う言語ですよね。そんな2つの言語でコミッターをしている変な人なんですが、もちろんRubyは大好きな言語です。
なんといってもRubyは書いていて楽しいですよね。さっと書けるし、文字どおりなんでもできる言語なので、思ったとおりに自由にプログラムが書けます。ライブラリもエコシステムも成熟しているので必要な機能をさっと作れる、これも良い部分ですね。
そうは言っても、Rubyにはなかなか難しいところもあります。当たり前のことかもしれませんが、Rubyで書いたプログラムを実行するためには、Rubyインタプリタを実行するマシンにインストールする必要があります。例えばWebブラウザ、モバイルOSなど、制限された環境だと、特にCRubyをインストールするのは難しいです。
というわけで、ユーザーにRubyをインストールさせない場合、たいていサーバーサイドで実行することになると思います。ただこれは、プログラムのユーザーにとっては優しいですが、プログラムの開発者にとっては優しくありません。特にちょっとしたプログラムを公開したいだけの場合、サーバーの管理コストとかは考えたくないですよね。
それからもう1つ大きな難しさとして、Rubyのインストールバトルがあります。Rubyのインストールは初学者が躓きがちなポイントで、環境ごとにトラブルシュートする必要がある難しい問題です。今ではruby-buildなどでかなり簡単になっていますが、それでも「BUILD FAILED」という文字列を何度も見たことがあると思います。
これらの難しさを解消することは、Rubyへの入り口を広げるだけではなく、みなさんの日々のプログラミングライフの中でRubyを使える機会を増やせるんじゃないかなと思います。
さて、ではどうやってこれらの難しさを解消するのがよいでしょうか? その選択肢の1つがWebAssemblyです。WebAssemblyははっきり言ってしまうと、プログラムの配布形式におけるゲームチェンジャーです。
おそらく名前しか聞いたことがないという方もいるので軽く解説すると、WebAssemblyはスタックマシン向けの命令フォーマットの仕様です。これはその名のとおり、Webブラウザでプログラムを動かすことをメインの目的として設計されています。
アーキテクチャやプラットフォームに依存せずにポータブルであること。ソースの言語に非依存であること。第三者から提供された信頼できないプログラムを安全に実行できること。というのがメインのデザインゴールとなっています。
WebAssemblyが何を解決するのかというのを先ほどの課題と照らし合わせてみると、現代では、どの環境にもブラウザがありますよね。Rubyがブラウザで動くようになれば実質的にどこでも動くようになります。ということで、プラットフォームサポートの幅がぐんと広がりますね。
もう1つのインストールの問題ですが、ブラウザ上で動けば明示的なインストールが必要なくなるので、初学者が環境構築で躓くことがぐんと減るのではないかと思います。
WebAssemblyのレイヤーとしては、C、C++、Swiftなどのさまざまな言語からコンパイルされるx86やARMと同様となります。コンパイルされた.wasmのファイルは、Webブラウザ上で実行されます。
具体的には、まずはコンパイラで.wasmファイルを作って、ブラウザ上でJavaScriptを使って、.wasmファイルをダウンロードして、最後にブラウザの実行エンジンでWasmプログラムを起動するという流れになっています。
さて、ここでCRubyを使ってRubyをブラウザ上で動かす場合を考えていきましょう。流れとしては、Cで書かれたRubyインタプリタを.wasmファイルにコンパイルして、それをブラウザ上にロードして、起動されたRubyインタプリタでRubyプログラムを実行します。
さて、ここで、どのぐらい手軽にブラウザで動かせるのかをデモしたいと思います。こんな感じでscriptタグを読み込みます。ここでRubyインタプリタがロードされているので、Rubyのスクリプトを書くことができます。「 type="text/ruby"」。なかなかかっこいいですね。
これでRubyを書けるので、とりあえず適当にHTTPサーバーを立てます。実際にブラウザで起動してみると「Hello」が表示されていますね。
(会場拍手)
というわけで、Rubyがブラウザで動いています。「やったね!」ということで。でも「Hello」というワードだけではつまらないですよね。もう少し複雑な、今日の運勢を占ってみましょう。先ほどと同じようにscriptをロードしておいて、とりあえずJavaScriptとの連携が見たいですね。このようにJavaScriptライブラリがあるので、こんな感じでRubyが書けます。
(会場拍手)
JavaScriptとも無事に連携できましたね。ここからおみくじを引いていきたいです。ズルをします。JavaScriptのAPIがそのままRubyのプログラムとして自然に書けます。これはRubyの表現力のおかげですね。これでイベントリスナーが書けて、ブロックでコールバックできるようになったので、ここで今日の運勢をサンプルしてみましょう。結果をDOMに書き込みます。
ということで、なんかエラーが出ていますが……なんて言っているんでしょうか。「undefind、buton」綴りが違うんですね。「t」が足りないと。今度こそ、いけていそうですね。おみくじを引きます。「あ〜、Unlucky」。
(会場笑)
これは何度でも引けるんですよね。「Lucky」になりました。
(会場拍手)
ということで、Rubyでおみくじが書けました。これはおもちゃですよね。もうちょっと複雑なデモをしたいと思います。今のコードは、github.com/ruby/ruby.wasmというリポジトリにあるので、あとでチェックしてみてください。
これが本題ですね。次のデモは、なんとirb(Interactive Ruby)が動きます。これ見えますかね? 普通のirbですね。これはブラウザで動いているんですよ。コンソールじゃないんですよ。ここで時間を表示してみますか。UTCですね。ここ実は、gemがインストールできて、syntax_treeというRubyのフォーマットがあったり、lintだったりできるやつがあるんですけど。
これはピュアRubyで書かれているので、ここのデモにちょうどいいんですよね。なかなかダウンロードが終わらないですね。…本当だ。これだからデモは怖いですね(笑)。今度はなんだ。gemだ、本当だ(笑)。みなさんのほうが詳しいですね。
(会場笑)
ようやくインストールできました。これで……え、今度は何。なんだなんだ。いいや、こっちができたので、じゃあsyntax_treeはいったん置いておいて、SVGのデモをしましょう。これはSVGをRubyで組み立てられるgemで、今適当に書いたんですが、こんな感じでSVGが生成されるわけですね。これはブラウザ上で動いているので、これをそのまま表示してみましょう。
(会場拍手)
よかった。こっちはうまくいった。ということで、irbがだいたい動きます。こちらはインターネットに公開しているので、ぜひお気に入りのgemで試してみてください。
いかがでしたか? ここからは、今デモしたWebAssemblyがどのように動いているのかを紹介します。
実はバニラなWebAssembly自体には、ファイルシステムへのアクセス方法は既定されていません。システムの時計にもアクセスできませんし、もちろんネットワークにもアクセスできません。では、先ほど見たTime.nowは何を返しているのでしょうか? お察しのとおり、WebAssembly自体でできないことは外側のホスト環境、ここではJavaScriptにやってもらおうという感じになっています。
実際にTime.nowが呼ばれると、CRubyの中でclock_gettimeシステムコールが呼ばれて、最終的にData.nowが呼ばれて結果が返ってくるわけですね。
ただ、ここでWebAssemblyが今やWebだけのものではなくなってきているという話が出てきます。sandboxによるセキュリティ機構やバイナリのポータビリティは、Webブラウザ以外の場所でもうれしいですよね。
例えば、サーバーレスプラットフォームはだいたい関数のロジックをデプロイするわけですが、プラットフォーム側がWasmさえサポートしていれば、ユーザーはいろいろな言語でロジックを書けるわけです。これはプラグインシステムなどでも同じようなうれしさがあると思います。というわけで、WebAssemblyはブラウザのJavaScriptと常に一緒に実行されるわけではないという状況になってきています。
そこで、WASIという標準化されたシステムコールの仕様が出てきました。WASIは、WebAssembly System Interfaceの略で、プラットフォームに非依存なシステムコールインターフェイスを定義します。システムスタックとしては、MuslなどのlibcがWASIのインターフェイスを通して実際のWASIの実装を呼び出します。
ここ数年、Node.js、Deno、WasmをCLIから実行するWasmtime、サーバーレス環境であるFastlyのCompute@EdgeやCloudflare Workers。また最近は、VSCodeの拡張機能がWASI対応をしたり、ログ収集ツールのFluent BitのプラグインシステムがWASIをサポートしたりしています。
また、言語側でもサポートが広がっています。CやC++、Rust、Swiftなどがサポートしていて、ここに今回Rubyが加わりました。ただ、他の言語とちょっと事情が違うのが、RubyはRubyインタプリタと.rbファイルを配布しないといけません。
あとは、そもそもWasmに対応しているブラウザ以外の環境だと、だいたいOne Binaryしか受け付けてくれないんですよね。「.rbファイルを別途ホストのファイルシステムに配置してから起動してくださいね」というのはなかなか面倒ですよね。というわけで、ホストから読み取っていた.rbファイルを、こうしてバイナリに埋め込むためのwasi-vfsという仮想ファイルシステムを開発しました。とりあえずRubyを動かすためにRead-onlyなインメモリのファイルシステムをサポートしています。
このVFSは、WASIのインターフェイスをプロキシする感じで動くので、実はRuby以外でも使えます。風の噂でCPythonがこれで使えたと聞きました。
ブラウザ以外で動く例として、サーバーレスのデモをしたいと思います。先ほど名前を出したFastlyのCompute@Edgeで動くデモを作ってきました。
今回のスクリプトはこんな感じです。FastlyのCompute@Edgeは、HTTPリクエストをCDNのEdgeサーバーでハンドルするサービスなので、リクエストを受け取ってレスポンスを返すロジックを書いていきます。
リクエストを受けるとWasmファイルは実行されるので、トップレベルにレスポンスを組み立てるロジックを書いていきます。これは単純にHTMLを組み立てて、現在の時間をTime.nowでWASIのインターフェイスを通して取得して、あとはRubyのバージョンや環境を書き出して、クライアントに送ります。
この.rbファイルをこんな感じで.wasmファイルに埋め込みます。この.wasmファイルにはRubyインタプリタと.rbファイルが含まれているわけですね。
今のスクリプトをデプロイした環境がこちらです。アクセスしてみてください。というわけでRubyがEdgeで動きました。
(会場拍手)
でもこれはクライアントと見分けがつかないですよね(笑)。
(会場笑)
リロードすると時間が増えます。楽しい。という感じです。
内容に戻ると、Ruby3.2ではWebAssemblyとWASIのサポートが入ります。ポートしたRubyがむき出しの状態だとみなさん使いにくいと思うので、ruby.wasmというリポジトリで、npmパッケージとビルド済みのWasmファイルを配布しています。実は先ほどのデモも、このnpmパッケージを使ってちょちょいと作っていました。みなさんぜひお気軽にお試しください。
(次回へつづく)
続きを読むには会員登録
(無料)が必要です。
会員登録していただくと、すべての記事が制限なく閲覧でき、
スピーカーフォローや記事のブックマークなど、便利な機能がご利用いただけます。
すでに会員の方はこちらからログイン
名刺アプリ「Eight」をご利用中の方は
こちらを読み込むだけで、すぐに記事が読めます!
スマホで読み込んで
ログインまたは登録作業をスキップ
関連タグ:
2025.09.08
部下が不幸になる上司のNG行動5選 マネジメントは「自律と統制」のバランスでうまくいく
2025.09.10
人生の差は20代で決まる “指示待ち人間”で終わらないために積むべき4つの経験
2025.09.16
日本人が英語学習で苦戦する根本的原因 「言いたいことの順番」が真逆になる英語と日本語
2025.09.10
「やりたいこと」はないが「課題解決」自体を楽しめる人 Googleの「優秀なエンジニア」の定義
2025.09.17
“仕事が遅い人”が会議でやりがちなNG行動 北の達人・木下勝寿氏が教える効率的な打ち合わせ術
2025.09.17
英語ネイティブは「would」をどう使っているか? 「Do you like〜」と「Would you like〜」の違い
2025.09.16
“できる仕事のキャパが10倍になった” 東証上場社長を変えた習慣「ピッパの法則」の効果
2025.09.11
自分の得意・不得意がわかるワーク 人生を再設計する「ライフキャリア」の見つけ方
2025.09.12
“起業が向いている人”と”経営が向いている人”は違う DMM亀山会長が語る、新規事業の生み出し方
2025.09.04
「管理職になりたくない問題」の原因は上司にもある 部下の昇進意欲を削ぐ行動
管理職は罰ゲームではなかった!マネジメントスキル、リーダーシップは財産に!
2025.07.31 - 2025.07.31
後回しを断ち切り“すぐやる人”になる最速メソッド|東証上場社長実践の後回し撲滅法
2025.06.24 - 2025.06.24
「因数分解! 売れない理由は、“売り方”じゃなく “見方”にある」 ~マーケティング×ビジネス数学で、売上を動かす本質をつかむ~
2025.08.06 - 2025.08.06
【板挟みに苦しむ管理職へ】忙しさから“本当に抜け出す”唯一の方法
2025.07.09 - 2025.07.09
「英語OS」を身につけよ! −思考プロセスをアップデートし、英語学習の遠回りを終わらせよう!
2025.07.05 - 2025.07.05