|
| 1 | +[[**Cheat Sheet**]](./cheat_sheet.md) |
| 2 | +[[**FAQ**]](./faq.md) |
| 3 | +[[**Complete Examples**]](https://github.com/ruby/ruby.wasm/tree/main/packages/npm-packages/ruby-wasm-wasi/example) |
| 4 | +[[**Community Showcase**]](https://github.com/ruby/ruby.wasm/wiki/Showcase) |
| 5 | + |
| 6 | +# ruby.wasm Cheat Sheet |
| 7 | + |
| 8 | +## Node.js |
| 9 | + |
| 10 | +To install the package, install `@ruby/3.2-wasm-wasi` and `@ruby/wasm-wasi` from npm: |
| 11 | + |
| 12 | +```console |
| 13 | +npm install --save @ruby/3.2-wasm-wasi @ruby/wasm-wasi |
| 14 | +``` |
| 15 | + |
| 16 | +Then instantiate a Ruby VM by the following code: |
| 17 | + |
| 18 | +```javascript |
| 19 | +import fs from "fs/promises"; |
| 20 | +import { DefaultRubyVM } from "@ruby/wasm-wasi/dist/node"; |
| 21 | + |
| 22 | +const binary = await fs.readFile("./node_modules/@ruby/3.2-wasm-wasi/dist/ruby.wasm"); |
| 23 | +const module = await WebAssembly.compile(binary); |
| 24 | +const { vm } = await DefaultRubyVM(module); |
| 25 | +vm.eval(`puts "hello world"`); |
| 26 | +``` |
| 27 | + |
| 28 | +Then run the example code with `--experimental-wasi-unstable-preview1` flag to enable WASI support: |
| 29 | + |
| 30 | +```console |
| 31 | +$ node --experimental-wasi-unstable-preview1 index.mjs |
| 32 | +``` |
| 33 | + |
| 34 | +## Browser |
| 35 | + |
| 36 | +The easiest way to run Ruby on browser is to use `browser.script.iife.js` script from CDN: |
| 37 | + |
| 38 | +```html |
| 39 | +<html> |
| 40 | + < script src= "https://cdn.jsdelivr.net/npm/@ruby/[email protected]/dist/browser.script.iife.js"></ script> |
| 41 | + <script type="text/ruby"> |
| 42 | + require "js" |
| 43 | + JS.global[:document].write "Hello, world!" |
| 44 | + </script> |
| 45 | +</html> |
| 46 | +``` |
| 47 | + |
| 48 | +If you want to control Ruby VM from JavaScript, you can use `@ruby/wasm-wasi` package API: |
| 49 | + |
| 50 | +```html |
| 51 | +<html> |
| 52 | + <script type="module"> |
| 53 | + import { DefaultRubyVM } from "https://cdn.jsdelivr.net/npm/@ruby/[email protected]/dist/esm/browser.js"; |
| 54 | + const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/[email protected]/dist/ruby+stdlib.wasm"); |
| 55 | + const module = await WebAssembly.compileStreaming(response); |
| 56 | + const { vm } = await DefaultRubyVM(module); |
| 57 | +
|
| 58 | + vm.eval(` |
| 59 | + require "js" |
| 60 | + JS.global[:document].write "Hello, world!" |
| 61 | + `); |
| 62 | + </script> |
| 63 | +</html> |
| 64 | +``` |
| 65 | + |
| 66 | +## Use JavaScript from Ruby |
| 67 | + |
| 68 | +### Get/set JavaScript variables from Ruby |
| 69 | + |
| 70 | +```ruby |
| 71 | +require "js" |
| 72 | + |
| 73 | +document = JS.global[:document] |
| 74 | +document[:title] = "Hello, world!" |
| 75 | +``` |
| 76 | + |
| 77 | +### Call JavaScript methods from Ruby |
| 78 | + |
| 79 | +```ruby |
| 80 | +require "js" |
| 81 | + |
| 82 | +JS.global[:document].createElement("div") |
| 83 | + |
| 84 | +JS.global[:document].call(:createElement, "div".to_js) # same as above |
| 85 | +``` |
| 86 | + |
| 87 | +### Pass Ruby `Proc` to JavaScript (Callback to Ruby) |
| 88 | + |
| 89 | +```ruby |
| 90 | +require "js" |
| 91 | + |
| 92 | +JS.global.setTimeout(proc { puts "Hello, world!" }, 1000) |
| 93 | + |
| 94 | +input = JS.global[:document].querySelector("input") |
| 95 | +input.addEventListener("change") do |event| |
| 96 | + puts event[:target][:value].to_s |
| 97 | +end |
| 98 | +``` |
| 99 | + |
| 100 | +### `await` JavaScript `Promise` from Ruby |
| 101 | + |
| 102 | +```html |
| 103 | +<html> |
| 104 | + < script src= "https://cdn.jsdelivr.net/npm/@ruby/[email protected]/dist/browser.script.iife.js"></ script> |
| 105 | + <script type="text/ruby" data-eval="async"> |
| 106 | + require "js" |
| 107 | +
|
| 108 | + response = JS.global.fetch("https://www.ruby-lang.org/").await |
| 109 | + puts response[:status] |
| 110 | + </script> |
| 111 | +</html> |
| 112 | +``` |
| 113 | + |
| 114 | +Or using `@ruby/wasm-wasi` package API: |
| 115 | + |
| 116 | +```html |
| 117 | +<html> |
| 118 | + <script type="module"> |
| 119 | + import { DefaultRubyVM } from "https://cdn.jsdelivr.net/npm/@ruby/[email protected]/dist/esm/browser.js"; |
| 120 | + const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/[email protected]/dist/ruby+stdlib.wasm"); |
| 121 | + const module = await WebAssembly.compileStreaming(response); |
| 122 | + const { vm } = await DefaultRubyVM(module); |
| 123 | +
|
| 124 | + vm.evalAsync(` |
| 125 | + require "js" |
| 126 | +
|
| 127 | + response = JS.global.fetch("https://www.ruby-lang.org/").await |
| 128 | + puts response[:status] |
| 129 | + `); |
| 130 | + </script> |
| 131 | +</html> |
| 132 | +``` |
| 133 | + |
| 134 | +### `new` JavaScript instance from Ruby |
| 135 | + |
| 136 | +```ruby |
| 137 | +require "js" |
| 138 | + |
| 139 | +JS.global[:Date].new(2000, 9, 13) |
| 140 | +``` |
| 141 | + |
| 142 | +### Convert returned JavaScript `String` value to Ruby `String` |
| 143 | + |
| 144 | +```ruby |
| 145 | +require "js" |
| 146 | + |
| 147 | +title = JS.global[:document].title # => JS::Object("Hello, world!") |
| 148 | +title.to_s # => "Hello, world!" |
| 149 | +``` |
| 150 | + |
| 151 | +### Convert JavaScript `Boolean` value to Ruby `true`/`false` |
| 152 | + |
| 153 | +```ruby |
| 154 | +require "js" |
| 155 | + |
| 156 | +JS.global[:document].hasFocus? # => true |
| 157 | +JS.global[:document].hasFocus # => JS::Object(true) |
| 158 | +``` |
| 159 | + |
| 160 | +### Convert JavaScript `Number` value to Ruby `Integer`/`Float` |
| 161 | + |
| 162 | +```ruby |
| 163 | +require "js" |
| 164 | + |
| 165 | +rand = JS.global[:Math].random # JS::Object(0.123456789) |
| 166 | +rand.to_i # => 0 |
| 167 | +rand.to_f # => 0.123456789 |
| 168 | +``` |
0 commit comments