2025-04

1. 概要

rbCanvas/p5 v0.5.1までは Opalによって Rubyのコードを JavaScriptに変換(トランスパイル)して実行していましたが、 v0.7.2では ruby.wasmを用いて Rubyのコードのまま実行する仕組みに変更されました。

p5.jsの機能を呼び出す際のオーバーヘッドが増えたため、プログラムによっては v0.5.1よりも 動作が遅くなるものもありますが、純粋な Rubyの仕様に基づいたプログラムを記述することができるようになりました。

また、実行時にエラーが生じた際に、これまでは元の Rubyのコード上でのエラー発生箇所を特定するのが 難しいケースがありましたが、v0.7.2では正確なトレース情報を提供できるようになりました。

なお、Rubyのコード実行前の構文チェック役として引きつづき Opalも部分的に利用されています。

その他、詳細については以下の記述をご確認ください。


2. 利用ライブラリ

(1)エディタ

機能 ライブラリ バージョン (参考)
rbCanvas/p5 v0.5.1での利用バージョン

エディタ本体

ace.js

1.38.0

1.6.0

メニュー構築

bootstrap.js

5.0.2

同左

Ruby構文チェック

opal.js
opal-parser.js

1.4.1

同左

(2)ランタイム

機能 ライブラリ バージョン (参考)
rbCanvas/p5 v0.5.1での利用バージョン

描画処理など

p5.js

1.11.2

1.8.0

機械学習

ml5.js

0.12.2

同左

プログラム実行

ruby-3_2-wasm-wasi
(browser.umd.js)
(ruby+stdlib.wasm)

2.3.0

-


3. 追加機能および変更点など

(1)エディタ

機能 備考

新たなタブでエディタを開くための項目を追加

歯車メニュー(ツール ; tools)の下
 menu
 [p5 テンプレート ; p5 template]
  p5用のテンプレートが表示された状態の
  タブが新たに開きます
 [コンソール (ブランク) ; blank]
  ブランク(白紙)状態のタブが
  新たに開きます
 [コンソール (サンプル) ; samples]
  コンソール用のサンプルが表示された状態の
  タブが新たに開きます

構文(シンタックス)エラー時の表示ダイアログを window.alertからカスタムダイアログに変更

出力例
 alert

一部メニュー項目にショートカットキーを設定

[CTRL] + R …​ 実行
[CTRL] + S …​ 保存

URLパラメータでサイト内のサンプルを読み込む機能を追加

APIリファレンスのサンプル編集などに利用


(2)追加メソッド

区分 メソッド 概要

Shape

beginGeometry

複合的な 3Dモデルの生成

endGeometry

3D Effect

roll

Transform

shearX

座標系の傾斜

shearY

Vector

(p5vector).slerp

P5Vector.copy

p5vectorオブジェクトのインスタンスメソッドに準拠して適宜追加

P5Vector.setMag

P5Vector.limit

P5Vector.reflect

P5Vector.slerp

P5Vector.magSq

P5Vector.heading

P5Vector.angleBetween

P5Vector.equals

P5Vector.array

Noise
(新規)

new

ノイズ

start

stop

amp

Speech
(新規)

new

音声による発話

speak

volume

rate

pitch


(3)その他

・rbCanvas/p5の実装などによる変更
1. エイリアス(別名)
内容 備考

1

キャメルケースで命名されているメソッドに対して、スネークケースのエイリアス(別名)を付与

(例) createCanvascreate_canvas など
エイリアス(別名)については、APIリファレンスの各メソッドのページに記載

2. 定数関連
内容 備考

1

定数の定義を rbCanvas/p5独自に拡充および調整

・0~9, A~Zなどのキーコードに対応する定義
・低音部の周波数に対応する定義
strokeCapで使用される定数
(詳細は 定数 を参照)

3. イベントハンドラ関連
内容 備考

1

マウスおよびキーボードに関するイベントハンドラについて、 ブラウザの標準的な動作を抑止できるように修正

イベントハンドラが falseを返した場合は JavaScriptの event.preventDefaultを呼び出し
(例) def mouseWheel …​ end

2

マウスホイールのイベントハンドラで、ブロック引数として event ではなく event.delta (ホイールの移動量)を受け取るように rbCanvas/p5独自に調整

(例) def mouseWheel …​ end

4. ユーザインターフェース用パーツ(p5lementオブジェクト)関連
内容 備考

1

p5elementオブジェクトのイベントハンドラに関するコールバック処理としてブロックのみを許可

v0.5.1では別途定義されたメソッドを指定することも可

2

p5elementオブジェクトのデフォルトの表示位置をメインキャンバスの外側(下部)に変更

v0.5.1ではメインキャンバス上の左上隅にデフォルト表示

3

p5elementオブジェクトのドロップダウンメニュー(選択リスト)で option メソッドの引数順序を逆転

(p5element).option
ラジオボタンでの optionメソッド呼び出しと引数の指定を揃えるため

5. イメージ(p5imageオブジェクト)関連
内容 備考

1

イメージの複製のために rbCanvas/p5で独自に追加した (p5image).clone メソッドは、p5.js標準の (p5image).get メソッドで賄えるため廃止

(p5image).get

2

同一イメージファイルを対象に loadImageメソッドを複数実行した場合、独立した別インスタンスをそのつど生成するように修正

loadImage
v0.5.1では、インスタンス変数が異なっていても実体は同じイメージを指しており、filterなどによる編集内容が相互に干渉

6. ベクトル(p5vectorオブジェクト)関連
内容 備考

1

P5Vectorモジュールのメソッドで、新たに生成されるベクトルを第3引数で受けとる仕様を割愛

新規ベクトルは戻値として受けとる仕様に統一
(例) P5Vector.add

7. リファレンス関連
内容 備考

1

APIリファレンスに掲載されているサンプルコードについて、ボタン押下によってエディタ上で編集できるように改善

edit

2

APIリファレンスの分類名を一部変更

RenderingCanvas
DOMHTML Element

3

APIリファレンスのサイドバーで、メソッドの並び順についを適宜調整

p5.jsに明文化されていないメソッドなどについても、把握できた範囲で情報を掲載


・p5.jsのバージョンアップによる影響
8. WEBGL(3D)
内容 備考

1

cameraメソッドのデフォルト位置の z座標の値が変更

詳細は以下を参照
camera
(p5camera).camera

2

perspectiveメソッドおよび frustumメソッドで視野に関するデフォルト値が変更

詳細は以下を参照
perspective
frustum
(p5camera).perspective (p5camera).frustum


・Opalから ruby.wasmへの変更による影響
9. Ruby全般
内容 備考

1

Integer同士の演算結果は Integer

v0.5.1では Rubyの Integerと Floatの区別はなく JavaScriptの仕様に基づき Number扱い

v0.7.2では Ruby本来の仕様になるため、
除算などの処理は注意が必要

2

クラス内のインスタンスメソッドで privateキーワードが有効

v0.5.1では無効 (Opalの制約)

3

upcase!などの破壊的メソッドも利用可能

v0.5.1では Inplemrnt Error (Opalの制約)

4

nilに対するメソッドなどのチェックが厳密化

v0.5.1では、たとえば「初期化されていない変数 @item 」に対して drawメソッド内で @item.draw とすると、グローバルの drawメソッドが呼び出されて Maximum call stack size exceeded となる事象あり

また、@item.width もメインキャンバスの幅が返されていたため、明示的なエラーにならない反面、予期しない挙動になるケースが存在

これらについて、rbCanvas/p5 v0.7.2ではいずれも実行時エラーとして検出

5

p5.js由来のハッシュの要素へのアクセスについてドット記法は不許可

v0.5.1では、たとえば textAlign メソッドの戻値のハッシュを参照する際に h.horizontalh.vertical などの記述でも可
v0.7.2では、Ruby本来の h[:horizontal]h[:vertical] に限定

6

putsによる式展開の出力の変更

v0.5.1では puts [1, 2, 3]の結果がフラットな値の羅列として出力
v0.7.2では [1, 2, 3] と出力

7

Ruby標準モジュールの利用が可能

ruby+stdlib.wasm を使用しているため、require することによって標準モジュールの利用が可能
(ただし、詳細な検証は未実施)

なお、v0.5.1での仕様と合わせるため v0.7.2では Date モジュールのみあらかじめ require 済み

また、エディタ上でユーザによって書かれた各ページのコードは実行時に rbCanvas/p5によって自動的に結合されて1ファイルとなるため、require は不要(従来どおり)


4. 実行時のエラー出力について

v0.7.2では、ruby.wasmからの実行時のトレース情報に基づいて Rubyのコードのエラー発生箇所が出力されます。

error

上図の例では、6行目の bar メソッドに対する引数の不一致がエラーの原因で、 6行目に対して ArgumentError が出力されています。

また、その表示の下には bar メソッドを呼び出したのが foo メソッド内の 10行目からであることが示されており、 さらにそれを呼び出したのが setup メソッド内の3行目という情報が出力されています。

このように、v0.5.1よりもエラー発生時の情報が詳しく出力されるため、 呼び出しに関する情報を順にたどっていくことによってコードのデバッグがしやすくなる効果が期待できます。


5. v0.5.1からの移行について

(1)HTMLファイルの互換性

v0.5.1のエディタ上で保存された HTMLファイルは、そのまま v0.7.2のエディタでも読み込むことができます。
なお、画像ファイルや音声ファイルなどの情報も一括して取り込まれます。

(2)数値の扱い

前述の 「Opalから ruby.wasmへの変更による影響」Integer同士の演算結果 にあるとおり、 整数の演算結果の扱いについては注意が必要になります。

 

1)

たとえば、ある値を 100で除算しようとして value / 100 と記述した場合、仮に value の値が 30 とすると、Opalベースのv0.5.1では数値はすべて Numeric型のため 0.3 という小数値が得られますが、v0.7.2では value が Integer型であれば 演算結果は 0 となります。

v0.5.1で動作していたコードを v0.7.2に移行した際に画面の描画などがおかしくなるようなケースが生じた場合には、数値の型を確認したうえで value / 100.0value.to_f / 100 など適宜必要な対応をおこなってください。

 

2)

繰り返し処理などをおこなう際に問題になりやすいものとして、構文やメソッドなどによっては Integer型を要求するものがあります。

v0.7.2では、たとえばメインキャンバスの幅を示す width というシステム変数は Float型として値を返しますので、そのままでは .times メソッドなどを使用することができません。

この場合、width.to_i.times { …​ } のように適宜 Integer型に変換して処理をおこなってください。

(3)メソッド呼び出し時のチェック

v0.5.1では、Opalおよび p5.jsの構造に依存してメソッドや引数などのチェックが比較的緩い状況になっていました。

v0.7.2では、rbCanvas/p5側でメソッドの有無のチェックや 引数の個数および型のチェックをおこない、許容外の場合にはエラーを出力するようにしています。

そのため、たとえば前述の nilに対するメソッドなどのチェック で記載したようなケースも含め、これまでは顕在化せずに通過していたような不整合などが v0.7.2ではエラーとして検知される可能性があります。


6. パフォーマンスについて

(1)実行時のオーバーヘッド

v0.7.2では、Wasmバイナリとして ruby+stdlib.wasm を使用しています。

これは Rubyの標準モジュールを含んでおり、また eval_async によって Rubyのコードを非同期実行することができるものです。

ただし、ファイルサイズが約30MBほどあり、ブラウザの初回起動時やリロード後などキャッシュが効いていない状況ではロードおよびコンパイルの処理がその都度おこなわれるため、コードの実行開始までのオーバーヘッドが大きくなるのが難点と言えるかもしれません。

より軽量の ruby.wasm (ファイルサイズは約14MBほど)を使用すればパフォーマンスは改善されますが、以下の点から ruby+stdlib.wasm を採用する方針としました。

  * ブラウザでキャッシュが有効になれば上記のオーバーヘッドはほとんど気にならない

  * ruby.wasm では eval_async による非同期実行がサポートされていないため、
    sleep メソッドなどの実行ができない

  * v0.5.1で対応していた Dateモジュールを利用するために標準モジュールが
   提供されている必要がある

  * 将来的に多くの標準モジュールをブラウザ上でも利用できるようにするための
   布石としてあらかじめ ruby+stdlib.wasm を採用しておきたい

  * Wasmに関する技術進歩によって軽量化/高機能化が進めば、
   先々はパフォーマンスの点については問題視されなくなるのではないか

(2)JavaScript呼び出し時のオーバーヘッド

v0.5.1では、Opalによって JavaScriptに変換(トランスパイル)する冗長さがありましたが、p5.jsの各関数を呼び出す際には JavaScriptの世界の中ですべて完結するので比較的ストレスなく連携がができていました。

一方、v0.7.2では ruby(+stdlib).wasm からの JavaScriptの呼び出しにかかるオーバヘッドが大きいため、とくにイメージのピクセル単位での処理についてはかなりパフォーマンスが落ちています。

ほかにも、ループ処理や再帰処理内で多量の JavaScript呼び出しをおこなうような場合は、v0.5.1の方がパフォーマンスがよいケースも散見されています。

パフォーマンスの改善については、今後も継続的に取り組んでいく必要があると考えています。


7. その他

v0.7.2は、当面のあいだ暫定版(β版)として公開をおこないます。

  top

rbCanvas/p5のトップページ上では引きつづき v0.5.1を現行バージョンとし、 v0.7.2のリファレンスに関してはエディタ左上のヘルプボタンをクリックして参照してください。

  help