【Ruby】Ruby.wasmを使ってみたい！

HTMLの上でRubyのコードを実行できるツールがあったので試してみました。

# 作業ディレクトリの作成

```sh
% mkdir ruby_wasm_test && cd ruby_wasm_test
```

# HTMLファイルの作成

```sh
% touch index.html
```

# サンプルHTML

以下のコードをコピーして、`index.html`に貼り付けます。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Ruby.wasm Playground</title>
  <style>
    body {
      font-family: sans-serif;
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      background: #f9f9f9;
    }
    #container {
      text-align: center;
    }
    #editor {
      margin-top: 20px;
      display: none;
    }
    textarea {
      width: 400px;
      height: 150px;
      font-family: monospace;
    }
    pre {
      text-align: left;
      margin-top: 10px;
      background: #eee;
      padding: 10px;
      border: 1px solid #ccc;
    }
  </style>
</head>
<body>
  <div id="container">
    <button id="showEditorBtn">Rubyコードを書く</button>

    <div id="editor">
      <textarea id="rubyInput" placeholder="例: 1 + 1"></textarea><br>
      <button id="runRubyBtn">▶ Go</button>
      <pre id="output">（ここに実行結果が表示されます）</pre>
    </div>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/@ruby/3.2-wasm-wasi/dist/browser.script.iife.js"></script>
  <script>
    // DOM要素を取得
    const showEditorBtn = document.getElementById("showEditorBtn");
    const editor = document.getElementById("editor");
    const rubyInput = document.getElementById("rubyInput");
    const runRubyBtn = document.getElementById("runRubyBtn");
    const output = document.getElementById("output");

    let vm;

    const initVM = async () => {
      try {        
        await new Promise(resolve => setTimeout(resolve, 500));
        
        // インストールしたrubyVMを使用
        vm = self.rubyVM;
        
        if (!vm) {
          throw new Error("Ruby VMが初期化されていません");
        }
        
        console.log("Ruby VM initialized successfully!");
        return true;
      } catch (e) {
        console.error("Ruby VM initialization failed:", e);
        output.textContent = `⚠ 初期化エラー: ${e.message}`;
        return false;
      }
    };

    // VMを初期化する
    initVM().then((success) => {
      if (!success) return;
      
      // エディターを表示するボタンのイベントリスナー
      showEditorBtn.addEventListener("click", () => {
        editor.style.display = "block";
        showEditorBtn.style.display = "none";
      });

      // Rubyコード実行ボタンのイベントリスナー
      runRubyBtn.addEventListener("click", () => {
        const code = rubyInput.value;
        try {
          const result = vm.eval(code);
          output.textContent = `=> ${result}`;
        } catch (err) {
          output.textContent = `⚠ エラー: ${err.message}`;
        }
      });
    });
  </script>
</body>
</html>
```

## htmlコードの中で必要なもの

* ruby-wasm-wasiパッケージの IIFE（即時実行形式）版スクリプト

```html
<script src="https://cdn.jsdelivr.net/npm/@ruby/3.2-wasm-wasi/dist/browser.script.iife.js"></script>
```

これを使用することによって、以下のことが実現可能になります。

* Ruby.wasm の実行に必要な WebAssembly モジュール（ruby.wasm）を自動で取得して初期化
* グローバルスコープに rubyVM オブジェクトを提供
* WASI（WebAssembly System Interface）の環境構築
* Rubyの eval 実行環境の提供

# index.htmlをブラウザで開く

以下のような画面が表示されます。

![スクリーンショット 2025-06-16 9.06.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711491/052d66ac-9a30-429c-879a-558f443bac59.png)

「Rubyコードを書く」をクリックしてください。

# コードを書いて実行

テキストエリアにコードを書いて実行すると、実行結果が下に表示されます。

![スクリーンショット 2025-06-16 9.10.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711491/1c257431-b27f-4fec-ad2c-72e7f3916894.png)

# まとめ

AWS SDK for RubyのAPI呼び出したりできれば、これだけでAIチャットとかできるんじゃないかなぁ

以上