-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #329 from ruby/katei/enhance-doc
doc: Add cheat sheet and FAQ
- Loading branch information
Showing
3 changed files
with
205 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,14 @@ It enables running Ruby application on browsers, WASI compatible WebAssembly run | |
|
||
Try ruby.wasm in [TryRuby](https://try.ruby-lang.org/playground#code=puts+RUBY_DESCRIPTION&engine=cruby-3.2.0dev) in your browser. | ||
|
||
## Quick Links | ||
|
||
- [[**Cheat Sheet**]](./docs/cheat_sheet.md) | ||
- [[**FAQ**]](./docs/faq.md) | ||
- [[**API Reference**]](https://ruby.github.io/ruby.wasm/JS.html) | ||
- [[**Complete Examples**]](https://github.com/ruby/ruby.wasm/tree/main/packages/npm-packages/ruby-wasm-wasi/example) | ||
- [[**Community Showcase**]](https://github.com/ruby/ruby.wasm/wiki/Showcase) | ||
|
||
## Quick Example: Ruby on browser | ||
|
||
Create and save `index.html` page with the following contents: | ||
|
@@ -17,7 +25,10 @@ Create and save `index.html` page with the following contents: | |
<html> | ||
<script src="https://cdn.jsdelivr.net/npm/@ruby/[email protected]/dist/browser.script.iife.js"></script> | ||
<script type="text/ruby"> | ||
puts "Hello, world!" | ||
require "js" | ||
puts RUBY_VERSION # => Hello, world! (printed to the browser console) | ||
JS.global[:document].write "Hello, world!" | ||
</script> | ||
</html> | ||
``` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
[[**Cheat Sheet**]](./cheat_sheet.md) | ||
[[**FAQ**]](./faq.md) | ||
[[**Complete Examples**]](https://github.com/ruby/ruby.wasm/tree/main/packages/npm-packages/ruby-wasm-wasi/example) | ||
[[**Community Showcase**]](https://github.com/ruby/ruby.wasm/wiki/Showcase) | ||
|
||
# ruby.wasm Cheat Sheet | ||
|
||
## Node.js | ||
|
||
To install the package, install `@ruby/3.2-wasm-wasi` and `@ruby/wasm-wasi` from npm: | ||
|
||
```console | ||
npm install --save @ruby/3.2-wasm-wasi @ruby/wasm-wasi | ||
``` | ||
|
||
Then instantiate a Ruby VM by the following code: | ||
|
||
```javascript | ||
import fs from "fs/promises"; | ||
import { DefaultRubyVM } from "@ruby/wasm-wasi/dist/node"; | ||
|
||
const binary = await fs.readFile("./node_modules/@ruby/3.2-wasm-wasi/dist/ruby.wasm"); | ||
const module = await WebAssembly.compile(binary); | ||
const { vm } = await DefaultRubyVM(module); | ||
vm.eval(`puts "hello world"`); | ||
``` | ||
|
||
Then run the example code with `--experimental-wasi-unstable-preview1` flag to enable WASI support: | ||
|
||
```console | ||
$ node --experimental-wasi-unstable-preview1 index.mjs | ||
``` | ||
|
||
## Browser | ||
|
||
The easiest way to run Ruby on browser is to use `browser.script.iife.js` script from CDN: | ||
|
||
```html | ||
<html> | ||
<script src="https://cdn.jsdelivr.net/npm/@ruby/[email protected]/dist/browser.script.iife.js"></script> | ||
<script type="text/ruby"> | ||
require "js" | ||
JS.global[:document].write "Hello, world!" | ||
</script> | ||
</html> | ||
``` | ||
|
||
If you want to control Ruby VM from JavaScript, you can use `@ruby/wasm-wasi` package API: | ||
|
||
```html | ||
<html> | ||
<script type="module"> | ||
import { DefaultRubyVM } from "https://cdn.jsdelivr.net/npm/@ruby/[email protected]/dist/esm/browser.js"; | ||
const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/[email protected]/dist/ruby+stdlib.wasm"); | ||
const module = await WebAssembly.compileStreaming(response); | ||
const { vm } = await DefaultRubyVM(module); | ||
vm.eval(` | ||
require "js" | ||
JS.global[:document].write "Hello, world!" | ||
`); | ||
</script> | ||
</html> | ||
``` | ||
|
||
## Use JavaScript from Ruby | ||
|
||
### Get/set JavaScript variables from Ruby | ||
|
||
```ruby | ||
require "js" | ||
|
||
document = JS.global[:document] | ||
document[:title] = "Hello, world!" | ||
``` | ||
|
||
### Call JavaScript methods from Ruby | ||
|
||
```ruby | ||
require "js" | ||
|
||
JS.global[:document].createElement("div") | ||
|
||
JS.global[:document].call(:createElement, "div".to_js) # same as above | ||
``` | ||
|
||
### Pass Ruby `Proc` to JavaScript (Callback to Ruby) | ||
|
||
```ruby | ||
require "js" | ||
|
||
JS.global.setTimeout(proc { puts "Hello, world!" }, 1000) | ||
|
||
input = JS.global[:document].querySelector("input") | ||
input.addEventListener("change") do |event| | ||
puts event[:target][:value].to_s | ||
end | ||
``` | ||
|
||
### `await` JavaScript `Promise` from Ruby | ||
|
||
```html | ||
<html> | ||
<script src="https://cdn.jsdelivr.net/npm/@ruby/[email protected]/dist/browser.script.iife.js"></script> | ||
<script type="text/ruby" data-eval="async"> | ||
require "js" | ||
response = JS.global.fetch("https://www.ruby-lang.org/").await | ||
puts response[:status] | ||
</script> | ||
</html> | ||
``` | ||
|
||
Or using `@ruby/wasm-wasi` package API: | ||
|
||
```html | ||
<html> | ||
<script type="module"> | ||
import { DefaultRubyVM } from "https://cdn.jsdelivr.net/npm/@ruby/[email protected]/dist/esm/browser.js"; | ||
const response = await fetch("https://cdn.jsdelivr.net/npm/@ruby/[email protected]/dist/ruby+stdlib.wasm"); | ||
const module = await WebAssembly.compileStreaming(response); | ||
const { vm } = await DefaultRubyVM(module); | ||
vm.evalAsync(` | ||
require "js" | ||
response = JS.global.fetch("https://www.ruby-lang.org/").await | ||
puts response[:status] | ||
`); | ||
</script> | ||
</html> | ||
``` | ||
|
||
### `new` JavaScript instance from Ruby | ||
|
||
```ruby | ||
require "js" | ||
|
||
JS.global[:Date].new(2000, 9, 13) | ||
``` | ||
|
||
### Convert returned JavaScript `String` value to Ruby `String` | ||
|
||
```ruby | ||
require "js" | ||
|
||
title = JS.global[:document].title # => JS::Object("Hello, world!") | ||
title.to_s # => "Hello, world!" | ||
``` | ||
|
||
### Convert JavaScript `Boolean` value to Ruby `true`/`false` | ||
|
||
```ruby | ||
require "js" | ||
|
||
JS.global[:document].hasFocus? # => true | ||
JS.global[:document].hasFocus # => JS::Object(true) | ||
``` | ||
|
||
### Convert JavaScript `Number` value to Ruby `Integer`/`Float` | ||
|
||
```ruby | ||
require "js" | ||
|
||
rand = JS.global[:Math].random # JS::Object(0.123456789) | ||
rand.to_i # => 0 | ||
rand.to_f # => 0.123456789 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
[[**Cheat Sheet**]](./cheat_sheet.md) | ||
[[**FAQ**]](./faq.md) | ||
[[**API Reference**]](https://ruby.github.io/ruby.wasm/JS.html) | ||
[[**Complete Examples**]](https://github.com/ruby/ruby.wasm/tree/main/packages/npm-packages/ruby-wasm-wasi/example) | ||
[[**Community Showcase**]](https://github.com/ruby/ruby.wasm/wiki/Showcase) | ||
|
||
# FAQ | ||
|
||
## Where my `puts` output goes? | ||
|
||
By default, `puts` output goes to `STDOUT` which is a JavaScript `console.log` function. You can override it by setting `$stdout` to a Ruby object which has `write` method. | ||
|
||
```ruby | ||
$stdout = Object.new.tap do |obj| | ||
def obj.write(str) | ||
JS.global[:document].write(str) | ||
end | ||
end | ||
|
||
puts "Hello, world!" # => Prints "Hello, world!" to the HTML document | ||
``` | ||
|
||
## How to run WebAssembly in Ruby | ||
|
||
Use [`wasmtime` Ruby gem](https://rubygems.org/gems/wasmtime). |