Skip to content

Scopeの隠蔽 #1028

@takejohn

Description

@takejohn

パッケージの利用者がインタプリタのScopeを直接操作できないようにAPIを変更したいです。

現在、Scopeクラスがパッケージ外にエクスポートされており、
また、Interpreterscopeプロパティがpublicとなっています。
これによって、スクリプトの実行中であっても、
パッケージ利用者がグローバル変数の操作(get(), exists(), getAll(), add(), assign())をすることが可能となっています。
また、optsプロパティの関数log(), onUpdated()により、変数の更新をリアルタイムに受け取れるようになっています。

将来、Scopeクラスには多くの変更が加わり、APIの後方互換性を維持するのが難しくなると考えています。

  • WebAssemblyとしてコンパイルする機能 #98 において、WebAssemblyとしてコンパイルする場合、ScopeをJavaScriptから使用できるようにするとオーバーヘッドが生じると考えられます。
  • Web workerで実行する機能 #175 において、Web workerで実行する場合、操作を非同期で行う必要があります。また、worker間での値のコピーによるオーバーヘッドも考えられます。
  • スコープがTemporal window #877 に基づいてスコープをTemporal Dead Zone方式にする場合、値の初期化の前に変数の巻き上げを行うため、APIの変更が必要と考えられます。

そこで、次のメジャーバージョンでは将来の変更に備え、ScopeクラスとInterperter#scopeの実装を隠蔽し、変数操作を以下に限定したいです。
(WebAssembly版InterpreterやWeb worker版Interpreterを実装するなら、ここでのInterpreterはインターフェースになって、ファクトリインターフェースも作ることになるかも)

  • Interpreterインスタンス化でのconsts引数による変数初期化
  • 実行メソッドexec()の返値による変数読み出し
    メソッドシグネチャのイメージ:
    public async exec(script?: Ast.Node[]): Promise<void>;
    public async exec(script: Ast.Node[], opts: { returnVariables?: false }): Promise<void>;
    /** `returnVariables` が `true` の場合は全ての変数、`string[]` の場合は配列に含まれる名前をもつ変数のみを返す */
    public async exec(script: Ast.Node[], opts: { returnVariables: true | string[] }): Promise<Map<string, Value>>;
  • onUpdated()Interpreterコンストラクタのoptsに追加し、log()onUpdate()optsで指定された場合のみ有効化

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions