この記事は何
Rubyはバージョン3.2からWebAssembly(WASM)に対応をしています。
この記事では、RubyのWASMパッケージであるruby.wasmについて調べたことを残しておきます。
WebAssemblyとは
WebAssemblyについては、MDN Web docsで以下のように説明されています。
WebAssembly は最近のウェブブラウザーで動作し、新たな機能と大幅なパフォーマンス向上を提供する新しい種類のコードです。基本的に直接記述ではなく、C、C++、Rust 等の低水準の言語にとって効果的なコンパイル対象となるように設計されています。
WebAssemblyはWebブラウザ上で実行可能なコードで、W3Cにより標準化されているため、Chromeをはじめとしたブラウザで同一の仕様で動作します。
また、ブラウザ以外でのWebAssemblyの環境の実行に関しての仕様をまとめたWebAssembly System Interface (WASI)というものも存在します。
MDNの説明の通り、WebAssemlyは直接書くことは少なく、 C、C++,Rustをはじめとした低水準のコードをWebAssemblyコードへコンパイルすることで、
それぞれの言語で実装した処理をWeb上で動作させることを可能にしています。
また、C、C++、Rustなどで実装されたプログラミング言語のランタイムもWebAssemblyコードで変換することができるため、
この技術を応用することで他言語もブラウザ上で実行させることが可能となります。
詳しくは↓の記事をご覧ください。
ruby.wasmとは
ruby.wasmはブラウザ上(WebAssembly上)でRubyの実行を可能にしたものです。
RubyのインタープリターはCで実装されているため、Cで実装されたインタープリターをWebAssemblyでコンパイルし、Rubyのコードをこのインタープリターに読み込ませることでブラウザ上でのRubyの実行を実現しています。
ruby.wasmを利用することで、↓のようにHTML上に書いたRubyのコードも実行できてしまいます。(https://github.com/ruby/ruby.wasm より引用)
<html>
<script src="https://cdn.jsdelivr.net/npm/ruby-3_2-wasm-wasi@1.0.1/dist/browser.script.iife.js"></script>
<script type="text/ruby">
puts "Hello, world!"
</script>
</html>
'js'というライブラリを用いることで、RubyからJSのAPIへのアクセスも可能です。('js'ライブラリはruby.wasmに標準で入っています)
require 'js'
div = JS.global[:document].createElement("div")
div.addEventListener('click') do |e|
puts 'Hello, World!'
end
より詳しい仕組みについては↓の記事にまとまっています。
ruby.wasmによって実現したこと
ruby.wasmによって実現したことは大きく二つです。
Rubyの実行環境を簡単に配布できるようになった
今までRubyの実行環境を用意するためにはそれぞれの環境によって色々試行錯誤して導入する必要がありました。
現在はdockerなどでだいぶ環境を用意するのは簡単になりましたが、簡単なスクリプトを実行したいだけのためにはまだまだ環境のセットアップは重たいものですし、スマホなどで環境を用意するのはまだまだ難しいです。
ruby.wasmはブラウザ上でインタープリターのJSファイルをロードするだけで、
どんな環境でも簡単にRubyのスクリプトを実行することができます。
また、WASIに対応しているため、WASIのランタイムであるWasmerやWasmtimeなどの環境さえ用意できてしまえばすぐにRubyのコードを実行、WebAssebly化したファイルの配布をすることができます。
Rubyでフロントエンドの実装が可能になったこと
どう使っていくかはまだ模索中の段階だと思いますが、Rubyをフロントエンドで使えるようになったのはRubyの可能性を広げる、大きな変化だと思います。
ruby.wasmを利用することでRubyだけで簡単なJSXの処理も書くことが可能です。
課題
ruby.wasmはとても魅力的ですが、まだgemなどの外部ライブラリの使用が難しかったり、Threadなどの一部のライブラリの未対応など、実際のRubyの実装体験とは異なるところは存在します。
しかし今度そのような課題も解決されていくと思いますし、いろいろな人が使い、試行錯誤することでどんどん便利になっていくと思うので、私もruby.wasmを使って色々試していきたいです。
参考文献