You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在浏览器WASM应用中从JavaScript调用Ruby方法

在浏览器中从JavaScript调用WASM化Ruby方法的正确方式

核心逻辑

Ruby编译为WASM后,其方法默认处于Ruby自身的作用域,不会自动暴露给JavaScript。必须通过显式绑定或指定接口,才能让JS访问到Ruby方法。

具体实现方案

方案一:将Ruby方法挂载到JS全局对象

编写Ruby代码时,把需要调用的方法绑定到$global(对应JS的window对象):

# 定义业务方法
def calculate_total(price, quantity)
  price * quantity * 1.08 # 加8%税费
end

# 暴露给JavaScript全局作用域
$global.calculate_total = method(:calculate_total)

将上述代码用ruby.wasm编译为WASM模块后,在HTML中加载并调用:

<script src="https://cdn.jsdelivr.net/npm/ruby-head-wasm-wasi@0.5.0/dist/browser.script.iife.js"></script>
<script>
async function initRuby() {
  const { DefaultRubyVM } = window["ruby-wasm-wasi"];
  const vm = await DefaultRubyVM();
  // 加载编译好的WASM文件
  await vm.instantiateStreaming(fetch('./app.wasm'));
  
  // 直接调用全局对象上的Ruby方法
  const total = window.calculate_total(100, 2);
  console.log(`最终总价:${total}`); // 输出:最终总价:216
}
initRuby();
</script>

方案二:通过RubyVM接口直接调用

如果不想污染全局作用域,可以通过vm.eval执行Ruby代码并获取返回值:

async function callRubyFunc() {
  const { DefaultRubyVM } = window["ruby-wasm-wasi"];
  const vm = await DefaultRubyVM();
  
  // 先在Ruby环境中定义方法
  await vm.eval(`
    def format_date(date_str)
      Date.parse(date_str).strftime("%Y年%m月%d日")
    end
  `);

  // 调用方法并转换结果为JS可识别类型
  const formattedDate = await vm.eval(`format_date("2024-05-20")`);
  console.log(formattedDate.toString()); // 输出:2024年05月20日
}
callRubyFunc();

关键注意事项

  • 作用域隔离:Ruby和JS的作用域完全独立,未显式导出的Ruby方法无法被JS直接访问。
  • 参数类型兼容:基础类型(字符串、数字)可自动转换,复杂对象需手动做序列化/反序列化处理。
  • 异步处理:WASM初始化和方法调用均为异步操作,需用async/await处理流程。

内容的提问来源于stack exchange,提问作者zachaysan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 05:40:31