跳转至

Emueraについての補足

元となったページ
eratohoまとめ V3 Emueraについての補足


開発者のためのEmuera講座

Emueraは動作環境であると同時に、開発者にとって非常に有益な機能を持った構文チェッカでもある。
しかし、最近の状況を見るにつけ、どうもこの便利な機能がうまく使われていないという感じなので、
簡単に開発者向けのEmueraの使い方をまとめてみる


1.デフォルト設定で使うべからず

Emueraのデフォルト設定はプレイオンリーの人向けのものであり、
構文チェック等の機能等が生かされないのだが、この設定でエラーが出ない=問題ないと勘違いしてしまいやすい。
実際はデフォルト設定では構文チェックの重要部分の一部がスキップされるので、見落とされる基本的な構文エラーは少なくはない。
(Lv2の警告すら余裕で見落としになる)
そこで、開発者向けとして、以下の設定を推奨する。

  • 解析タブ

ロード時にレポートを表示するにチェック
ロード時に引数をチェックする常に行うor更新されていれば行う(なるべく前者を推奨だが、好み)
表示する最低警告レベル0 (エラーとかではないが、基本的な構文ミス等もないにこしたことはない)
関数の呼び出し系は最近のCALLFORM系が多用されるコードでは重要ではないので、好みでOK

  • 環境タブ

関連づけるテキストエディタ:自分が普段使ってるテキストエディタのパス
コマンドライン引数:そのエディタで行指定してファイルを開く時のコマンドライン引数(使ってるソフトのヘルプ等を参照のこと)
これでエラーが出たときにエラーが出た行の所をクリックすれば、自動的にエディタ上でその場所が開くようになる


2.解析モードというオプション

Emueraには解析モードという特殊な起動モードがある。
これはERBファイルorフォルダをEmuera.exeにドラックアンドドロップすることで立ち上がるものだが、
上で書いたような開発者向け設定で自動的にチェックを行い結果をAnalysis.logに出力してくれるモードである。
バリアント上で行えばcsvのデータも勘案した上で解析するので、基本的な構文チェックには十分な機能である。
普段使いでは起動の速いオプションにしたいが、開発の時にはしっかりと構文チェックをしたい人にはおすすめのモードである。
なお、解析モードでは、普段の起動にはない、ERBファイル毎の関数名一覧出力も行ってくれる


3.最近の構文解釈周りの強化

1807v5以降ではEmueraの構文チェック機能と開発者向け機能が強化されている。

  • A.関数呼び出しスタック

実行中エラーでは、今いる行のある関数から順に呼び出し元の行、さらに呼び出し元の行のある関数の呼び出し元…
と、どのように関数が呼び出されたかを表示するようになった。
汎用の式中関数中でのエラーなど、どこから呼び出された時に問題が起こったかとかの洗い出しに便利である。

  • B.起動時の変数チェックでの配列要素外参照のチェック追加

起動時に変数の引数の内定数のものについては、その時点で要素範囲内かのチェックを行う処理を追加した。
これで、定数の場合にはミスで範囲外を指しているのを起動時に報告してくれるようになった。

  • C.エラーを投げるTHROW

THROW命令はその行に到達した時点で、強制的にエラーを投げる命令である。
デバッグでの特定条件の確認等使い道は様々である。

以上のようにEmueraをうまく使うことで、簡単な構文エラーが残ったままのコードをうpしてしまうといったことはほぼなくせるので、
バリアント作者、口上作者、パッチ作者問わず、しっかりと使いこなしてほしい。


4._fixed.configの使い方

まず最初に、バリアント側で何かしら動作環境の設定を行いたい場合、emuera.configを使ってはいけない。
何故かといえば、emuera.configはユーザー側が自身の環境を定義するためのものであり、
ユーザーによって上書きされることが前提だからである。
(ユーザー側は他のバリアントからコピペする等の運用が想定される)

では、バリアント側で設定を固定したいときにどうするか?というと、CSVフォルダにある_fixed.configの出番となる。
_fixed.configで指定された設定はユーザー側で上書きすることができず、常に_fixed.configの指定が優先される。
これは、描画方法やセーブデータ形式など、設計レベルと言える設定に対して非常に効果的である。

似たファイルに_default.configがあるが、こちらはユーザー設定がない場合のデフォルト値を指定する仕様となっており、
現実的にはあまり出番がないものとなっている。


Q&A

Q:なぜEmueraは起動に時間がかかるのか

A:Emueraは起動時に全てのコードを読みIF~ENDIFCALL等の対応のチェックをしています。そのため起動に時間を要します。
しかし、このおかげで実際のスクリプトの処理はeramakerより速くなっています。
(描画処理が律速なので実感することはできませんが)
さらに起動時にエラーチェックできるのもこの実装のおかげです
ここらへんは完全に起動速度と起動後の処理速度等がトレードオフになってます。
1.735以降の文字列読み込みパース処理の高速化で起動時間は大幅に改善されました

Q:Emueraの描画遅すぎ

A:実のところC#はあまりグラフィックの描画に優れた言語ではありません。そのためこれは半ば仕様と言えます。
現在のGDI・GDI+ではなくOpenGLやDirectXを使えば速くなる「かも」しれませんが、そこまで手を出す余力は作者にはありません。
挑む勇気のある方がいればやってみるといいかもしれません。

以下、Workaround:
多くの場合はデフォルトの設定でそれなりの速度になるはずですが、RadeonHD系はPowerPlayの仕様によってGDIの描写が遅いので、GDI+を使うGraphics+イメージバッファ使用の設定にした方が速くてちらつきの少ない描写になるようです。
(HD4XX0系ならCCCでクロック固定という方法もあるが、素人にはおすすめできない)
また、古いマシンではFPS設定を落とすのも効果的です。

Q:_Repalace.csvでできる内容と書式は?

A:以下の通りです

  • お金の単位
  • 内容:所持金の表示でのお金の単位を指定
  • 書式:お金の単位, <単位に使う文字>
  • 単位の位置
    • 内容:所持金の単位を数値の前に付けるか後ろに付けるか
    • 書式:単位の位置, <前or後>
  • ファイル読み込み中の表示
    • 内容:起動読み込み時に詳細表示しない場合に表示される文字列を指定
    • 書式:起動時簡略表示, <表示する文字列>
  • SHOPで販売アイテムとして認識するアイテム数
    • 内容:SHOPで販売アイテムとして取り扱うITEMの数値の上限を指定
    • 書式:販売アイテム数, <上限ITEM番号>
  • DRAWLINEに使う文字
    • 内容:DRAWLINEの線に使う文字(列)を指定
    • 書式:DRAWLINE文字, <使う文字列>
  • BARで使う文字の指定
    • 内容:BARに使う文字の指定(文字列を用いた場合、正常動作を保証しません)
    • 書式:BAR文字1, <値の範囲内の表示に使う文字>
         BAR文字2, <値の範囲外の表示に使う文字>
  • システムメニュー文字列
    • 内容;読み込み終了後のシステムメニューの文字列を指定
    • 書式:システムメニュー0, <最初からはじめるを置き換える文字列>
         システムメニュー1, <ロードしてはじめるを置き換える文字列>
  • COM_ABLE初期値
    • 内容:@COM_ABLEXXがない場合にその返り値をどうするかを指定
    • 書式:COM_ABLE初期値, <0 or 1>
  • 汚れの初期値
    • 内容:STAIN変数の初期値を指定
    • 書式:汚れの初期値, <各配列要素の初期値(/で区切る)>
  • TINPUT系の時間切れ時の表示内容
    • 内容:TINPUT系で時間切れになったときに表示する文字列
    • 書式:時間切れ表示, <表示する文字列>
  • PALAMLVの初期値
    • 内容:PALAMLV変数の初期値を指定
    • 書式:PALAMLVの初期値, <初期値"/"区切りで>
  • EXPLVの初期値
    • 内容:EXPLV変数の初期値を指定
    • 書式:EXPLVの初期値, <初期値"/"区切りで>
  • PBAND:0変数の初期値を指定
    • 内容:PBAND:0変数の初期値を指定
    • 書式:PBANDの初期値, <値>

Emueraの仕様の補足

REPEAT~RENDFOR~NEXT)の変てこな仕様

eramakerでは以下のコードではループを回さない仕様になっている

ERB
GOTO $TEST  
REPEAT 10  
    ;~以下処理~  
    $TEST  
REND  

では、以下はどうなるか?

ERB
REPEAT 10  
    ;~以下処理~  
    $TEST  
REND  
COUNT = 0  
GOTO $TEST  

答えは、「REPEATを通ってないにも関わらずループが回る」である。
eramakerの仕様として、
「一度でもループに入れば、それ以降はGOTOREPEATを通さずに中に飛び込ませてもループを回す」
という実に面妖なものが存在しているのである。
Emueraでもこれは当然再現されている。間違っても使うべき処理ではないことだけは間違いないが。


CONTINUEの処理に関して

ループ処理に欠かせないCONTINUEBREAKの2命令
しかし、ループから強制的に抜けるBREAKの単純明快さの一方、
CONTINUEの処理は意外と勘違いされている。
この勘違いはDO~LOOP構文で出現する。

ERB
DO  
    ;(処理)  
    CONTINUE  
LOOP 0  

このコード、CONTINUEがあるので一見無限ループにも見えるが、
実はDO~LOOPの中は1回しか実行されない。
これはCONTINUE本質的にはループの最後に飛ぶという仕様だからである。
つまり、このループの処理は
CONTINUELOOP 0の判定→判定結果は偽なのでループを抜ける
ということになっている。


文字列とRETURNFに関する面妖な仕様

ユーザー定義の式中関数では識別子#FUNCTIONSを宣言することで
RETURNFで文字列を返す関数にすることができる。
ところが、このRETURNF文字列に関してはやや面妖な仕組みになっている。
RETURNFで文字列を返す場合の書式は、
PRINT系での表示や文字列代入等とは異なるルールになっている。
具体的には以下のとおりになる。

文字列の種類 書式
単純文字列 "文字列" RETURNF "テスト"
文字列変数 変数名 RETURNF STR:0
FORM文字列 @"FORM文字列構文" RETURNF @"%STR:1%{A:2}\@(LOCAL) ? あ # い\@"

最後のFORM文字列については@"~"を使わないとエラーになったりするので、
特に注意が必要である。


3次元配列とその制限

Emueraでは3次元配列を用意している。

TA:XX:XX:XX および TB:XX:XX:XX  
配列要素は100×100×100で計100万個である。
~~なお、制限として配列サイズを変えることができない~~
1732aより100万個を上限に配列サイズを変更可能に


インクリメント、デクリメントの拡張

前置・後置、文中での使用等色々対応してあります。
ほぼ普通のCプログラムと同様の感覚で使えるはずです。


文字列演算

最近のEmueraでは文字列演算で*=を使えるようになっていたりする。
使い道があるかどうかは実装した本人にも謎。


PRINTCPERLINE()の意味

configにPRINTCを並べる数という項目があるが、実はこれは調教コマンドの表示ぐらいでしか使われていない。
つまり、スクリプトからPRINTC系を使った場合は設定に応じた自動的な改行は行われない。
それでもUSERCOMのコマンドなんかを調教コマンドと同じように表示したい!という場合にこのコマンドの出番となる。
ようは、このコマンドで設定を読み取り、それにあわせて改行を行うようなコードを書けばよいのである。


DO~LOOP命令

書式:

ERB
DO 
    ;(命令)
LOOP (条件)  

補足:
WHILE~WENDループは最初にWHILEの条件を満たさないと中の処理は一切行われない。
それに対し、DO~LOOPでは1回ループ内の処理を行った後LOOPの行でループするか否かを判定する。
最低でも1回は処理が行われていることが確定しているなら、DO~LOOPを使った方がスマートなコードになる。


REUSELASTLINEの仕様の変化

REUSELASTLINEは最初に実装された[私家改造]1.52q rev.2と本家に取り込まれた1.60以降で仕様が異なっている。
具体的には元々は、

  • 前の行を消して、次の行を追加する時に消去される行を表示する

だったものが

  • 次の行を追加する時に消去される行を表示する

に変わっている。

そのため、INPUTに対し、無効な入力の時に入力した値を消そうとした場合、
元の仕様であれば、

ERB
REUSELASTLINE (警告文)  

のみでよかったが、現在は

ERB
CLEARLINE 1
REUSELASTLINE (警告文)  

とする必要がある。

なお、@USERXXX系の処理では今までどおり
REUSELASTLINE_ (_は半角スペース)
のみで動作するようになっている
(この場合の処理は内部的に行われるのでCLEARLINEが必要ない)

なお、この仕様の違いについては、また変えるのも混乱を招くということで元に戻さないことが決まっている(作者同士の直接対話によって決定)


Bit演算系命令

使えると便利だが、とにかくややこしいことに定評のあるBit演算。
Emueraでは1pNのような2進法表記が実装されたり、多くのBit演算向け演算子が追加されたりと格段にBit演算をやりやすい実装にはなっている。
とはいえ、プログラミング経験者ならともかく、そうでなければこの実装でもつらいというのが実際の所。
そこで、以上の方法とは別に、GETBITSETBITCLEARBITINVERTBITを用意している。
参考:リファレンス/BIT操作系

書式:

ERB
GETBIT (操作する変数)、(ビット位置)  
;対象変数の2^(ビット位置)のビットを取得  
;(GETBITは文中関数として使える)  

SETBIT (操作する変数)、(ビット位置)  
;対象変数の2^(ビット位置)のビットを1にする  

CLEARBIT (操作する変数)、(ビット位置)  
;対象変数の2^(ビット位置)のビットを0にする  

INVERTBIT (操作する変数)、(ビット位置)  
;対象変数の2^(ビット位置)のビットを反転(0→1、1→0)にする  

この方法の利点は、

  • いちいち対象になるビットの値を計算する必要がない。
  • ビット位置の指定は1pNと違い変数が使えるので処理の一元化を狙える。

欠点は

  • わかってる人からすればまだるっこしい。
  • 演算子等を使った方が格好良く見える

である。


Shift-JISとUnicodeでの文字列処理の違い

Emueraでは基本的に文字列長取得の命令が3つ用意されている。

ERB
STRLEN (文字列)  
STRLENS (文字列式)  
STRLENFORM (FORM構文)  

これらはいずれも、Shift-JISとしての文字列長を取得している。
これに対して、

ERB
STRLENU (文字列)  
STRLENSU (文字列式)  
STRLENFORMU (FORM構文)  

はユニコードとして文字列長を取得する。
最大の違いはShift-JISは漢字1文字を2文字とカウントするのに対して、ユニコードでは漢字も1文字でカウントするところである。


LOCAL変数であっても避けるべきこと

LOCALは非常に使い勝手のよい変数であるが、それでもERBの仕様上避けるべきである事象は存在する。

  • 同じイベント関数間を跨いだ使用

イベント関数はERBの仕様により複数定義してよいことになっている。
これはLOCALも全ての関数で共用になることを意味しており、
同じイベント関数間を跨ぐ形のLOCALに依存する処理は
他の同名関数の割り込みによって破綻する恐れが極めて高い
こういう目的にはTFLAG等を使うことをおすすめする

  • LOCAL@~の使用

LOCAL変数はその関数の外からLOCAL@で参照ができるようにはなっている
しかし、これは「デバッグのため」の措置であり、
値を確認するだけの場合であれば特に問題にはならないが、
代入し始めるとバグの要因にもなるし、デバッグも難しくするため
通常のコードでこれを使うことは全く薦められない
(将来的にはLOCAL@~は読み込み専用にしたいところ)
それをしないで済む実装系を考えることをオススメする

  • static変数として使うこと
    LOCALは関数が終わっても値が保持され続ける、
    つまりCでいうstatic(静的)な変数に近い挙動をする
    だが、だからといってLOCALをstaticな変数として使うことは避けるべき
    これは以下のようなコードを考えるとわかる
ERB
@TEST  
IF LOCAL == 0  
    ;~  
ELSEIF LOCAL == 1  
    ;~  
ELSE  
    ;~  
ENDIF  
LOCAL = (何かしらの条件に依存して決定)  

このコードは最後に設定したLOCALの値で次の挙動が決まる
LOCALはstaticなのだから一見問題なさそうに見えるが
このコード、セーブデータのロードを挟むと破綻する恐れがある
LOCALはセーブデータに保存されない変数であり、

  • タイトルに戻る
  • セーブデータのロード

等によって値は破棄される
つまり、前回設定した値に依存する処理は簡単にバグの原因になるのである
LOCALはあくまでもその1回の処理で閉じる使い方をするべきである


IFを使うべきかSELECTCASEを使うべきか

IFSELECTCASEA = RAND:5後にAで分岐といった場合には
どちらも使っても同様なコードが書けるが、
その処理速度には大きな開きがあり、
IFの方がSELECTCASEの倍ほどの処理時間を要する
上の例のような単純な値分岐の場合には
IFよりもSELECTCASEを使う方が効率がよいと言える

なお、口上で同じ事をやる場合にはPRINTDATA系を使う方が
コードが短く、処理も速い場合があることを明記しておく


CALLFと疑似セッター

CALLF命令は

式中関数を呼び出し、その返値は無視する  

と使い道がなさげな命令である。
しかし、次のような使い方が存在する

ERB
@SET_VALUE(ARG, ARG:1)  
#FUNCTION  
RETURNF VALUE("SET", ARG, ARG:1)  

@GET_VALUE(ARG)  
#FUNCTION  
RETURNF VALUE("GET", ARG)  

@VALUE(ARGS, ARG, ARG:1)  
#FUNCTION  
IF ARGS == "GET"  
    RETRUNF LOCAL:ARG  
ELSEIF ARGS == "SET"  
    LOCAL:ARG = ARG:1  
ENDIF  

こうすると、関数@VALUELOCALLOCAL@を使わずに参照可能になる。
一文字変数を使わずに複数の関数をまたいで配列を参照したい場合に有用ではある。


色々小難しい小話

私家改造でのスクリプト処理高速化の裏話

最近の私家改造では、スクリプト処理の高速化をはかったわけだが、
その中身は非常にトリッキーなものである。

これまでのスクリプト処理は簡単に書くとこんな感じである

(メインルーチン)→(スクリプト実行開始)→(処理準備)  
→(スクリプト実処理)→(無限ループ判定ルーチン)  
→(メインルーチン)  

これが1行ごとに繰り返されていたのが既存のコードである。
見ればわかるように、これは非常に効率の悪い処理である。
これを現在の私家改造では以下のように作り替えた。

(メインルーチン)→(スクリプト実行開始)  
→{(処理準備)→(スクリプト処理)→(無限ループ判定)}×n  
→(メインルーチン)  

ポイントは2行目。こちらの処理ではメインルーチンに戻る必要が生じない限り、
スクリプトの実行を延々とループさせることで、関数の呼び出し回数を減らすことに成功している。
さらに、一部の使用頻度の高い処理については特別な処理パスにすることで、
より処理時間を減らすことでREPEAT~RENDなどの高速化に成功している。


Emueraのエラーチェックの内容

Emueraは起動後コードを読み込み、エラーがあればそれを表示してくれる。
この表示には2パターンあり、

  • ファイル読み込み時に表示されるエラー
    • *****.ERB読み込み中…の下に表示されるエラー
  • ファイル読み込み後の構文チェックで表示されるエラー
    • ファイル読み込み終了後、タイトル表示までに表示されるエラー

であり、これはコードチェックのタイムスケールの違いによって区分される。
具体的には以下のように順番にエラーをチェックしている。

  • ファイル読み込み時のエラーチェック
    • 1 解釈可能な行かの確認におけるエラーチェック
      • a.[SKIPSTART]#で始まる行
        • 正しく用いられているか確認、エラーならエラー表示
      • b.関数宣言行
        • 宣言の書式が正しいか確認、エラーならエラーを表示
      • c.+ or -で始まる行
        • 前置のインクリメント・デクリメントであるか確認、そうでないならエラー表示
      • d.命令・変数で始まるはずの行
        • まず、最初の来る文字列が命令もしくは変数かを確認
        • どちらでもなければエラー表示
        • そもそも最初に来る文字列が不正(\$などのあるはずのない記号を含んでいる)な場合は例外を吐いてここで読み込み打ち切り(1731t以降では打ち切らないように変更)
      • e.変数への代入行と予想される場合
        • 代入の形になっているかチェック、なってなければエラーを表示
    • 2 ファイル読み込み後の構文チェックで行われるエラーチェック
      • a.宣言された関数の中身のチェック
        • #FUNCTION宣言された関数なら、使えない命令がないかのチェック
        • 「起動時に引数を解析する」場合は引数が正しい書式になっているかチェック
        • IF~ELSEIF~ELSE~ENDIFREPEAT~RENDなどの対となって使われる命令の対応関係のチェック
        • CALLなどの飛び先チェック(CALLFORMのような実行時に飛び先が決定される命令はチェックせず)

PRINT系とPRINTFORM系の処理量の違い

変数の中身を含まない平文を表示するときにはPRINT系とPRINTFORM系どちらが内部処理量が少ないか。
答えは(問題にするまでもなく予想はつくだろうが)PRINT系である。
PRINT系は引数をそのまま表示するため非常に処理量が少ない。

  • PRINT系
    引数チェック:引数をそのまま文字列として代入
    命令実行内容:引数を取り出し、そのまま表示用関数に渡すだけ

  • PRINTFORM系
    引数チェック:引数を取り出し、変数の存在などをチェックしstring.Format書式に対応した文字列として保存
    命令実行内容:引数を取り出し、書式に変数の中身を入れる処理を行い、表示用文字列を作成して表示用関数に渡す

このようにPRINT系とPRINTFORM系では平文だとしても処理量には雲泥の差がある。
ちなみに1755aでPRINTFORM系に平文を与えた場合の処理速度が大幅に改善されたため、差はかなり縮まったと思われる(それでも明らかに遅いだろうが)


IF文の条件判定の順番

次のようなIF文を考える

ERB
IF A && (B || (C && D))  
この構文において条件A~Dはどのような順番で判定されるだろうか?
(簡単化のため短絡評価は考えないものとする)
単純に考えれば()内が優先されるので、C→D→B→Aとなると思われるが、実際のEmueraの処理ではA→B→C→Dの順で判定される。

なぜこのようになるかと言うと、これはEmueraでの構文の処理法に由来する。
上の構文はEmueraでは次のように解釈される。

1, Y = C && Dとして、  
    IF A && (B || Y)  
1. X = B || Yとして、  
    IF A && X  

で、実際の処理は次のようになる。

1. A && Xを評価  
    1a. 左辺のAを評価  
    1b. 右辺のXを評価→X = B || YなのでB || Yの評価へ進む  
1. B || Yを評価  
    2a. 左辺のBを評価  
    2b. 右辺のYを評価→Y = C && DなのでC && Dの評価へ進む  
1. C && Dの評価  
    3a. 左辺のCを評価  
    3b. 右辺のDを評価  

以上より判定される順番はA→B→C→Dとなる。
考えればわかるが、判定結果は正しくなるため、この方法には何の問題はないし、短絡判定は左辺優先なのでむしろこうした方が合理的なのである。
(そもそも左辺が偽なら右辺の()内は見る必要がないので処理が減るし、左辺が真の場合でも行われる処理は右辺の()内を先に評価した場合と変わらないため、総合的に見れば処理量は減ることになる。
そういう意味ではEmueraのみを想定しているコードではエラーにならない範囲で最も成立しにくい条件を最初に持ってくるというのは極限論的には無意味なコーディングではない。
もちろん現実的な話をするなら、Q&Aに書いたようにEmueraの処理の律速は描画処理なので、ここにこだわったところで処理速度に有意な差が出ることはない。)


なぜVARSETは速いのか

変数配列全体を指定した値で初期化するVARSET命令は同様の実装である

ERB
REPEAT N(配列の大きさ)  
    A:N = 0  
REND  

に比べて、処理速度にして軽く見積もっても1万倍以上は速い。
VARSETは配列要素数が100万個でもほぼ一瞬で処理が終わる)
これにはちゃんとした理由がある。

VARSETは呼び出されると、内部で与えられた配列を呼び出し、指定された値を代入するループ処理を行う。
この内部で行われるループ処理は実行時に最適化され、非常に高速に実行される。
一方、REPEAT~RENDの場合は以下のような処理が行われる。

1. REPEATに入る  
    (最初ならCOUNTを0にセット、  
    RENDから飛んできたらCOUNTに1を追加し終了判定)  
2. A:COUNT = 0を実行  
3. RENDの行は何もせずにREPEATの行に戻る  

(この1~3が設定された回数繰り返される)
このようにREPEAT~RENDの場合は変数への値代入処理だけでなく、3行のコードを駆動するための処理が増える。
結果、単純に処理量が増えるだけでなく、処理の複雑化により実行時の最適化も難しくなるため非常に時間がかかってしまう。
一般に、ERBで書かれたスクリプトと同じ処理をする内部命令を実装すれば、内部命令の方が格段に速くなることがほとんどである。
(特に配列に対してループを回すような処理であれば)
ただし、有意な差が出るような長く重いコード自体少ないのでこの違いを体感できる事例はそれほど多くはなかったりする。


コード読み直しの仕様とメモリ消費量の増加

今のEmueraにはERBファイル再読込の機能があるが、これは使う度にメモリ消費量が増加していく。
これには避けられない要因がある。
EmueraのERBコードの処理では、起動時に全てのコードを一行ずつ読み込み、クラスに押し込めて管理しているが、このとき、今いる行の次の行の情報を保持するようになっている。

さて、ERBの再読込はシステム側の入力待ちだけでなくINPUTなどの入力待ち命令中でも行えるが、
この時今いるINPUTを含む関数が記述されているファイルが再読込されてコードの情報が置き換えられるといったいどうなるか?
答えは簡単である。

Emueraは実行するコードを見失いエラーを出す。

そのため、再読込時には既存のコードを捨てることができない。

よって、すでに読み込んであるコードとは別に新たにコードをスタックする仕組みになっている。

そして、関数の定義情報を書き換えることで新規コードの方を実行するようになっている。
この仕様により動作中の関数は一旦終了し再度呼ばれるまでは古いコードに従い動作することになるが、これは防ぎようがない事象である。
また、再読込後の古いコードであるが、再読込ファイルのコードの追加後は新旧の区別が困難であるため、消さずに放置している。そのため、再読込の度にコードのスタックが増大しメモリ消費量が増えていくことになる。
そのため、開発中等で必要になる場合以外は使わない方が安全な機能ではある。