====== 関数の定義・呼び出し ======
[[erabasicリファレンス|リファレンストップ]] · [[erabasicリファレンス_総索引|名前の総索引]]
関数の定義、引数・戻り値、呼び出し、ユーザー定義式中関数を調べます。
===== 自作関数における引数指定 =====
※1.54uまでと1.60以降で仕様が異なります!※\\
==== 書式 ====
関数側
@(関数名),(引数1),{(引数2)....}
引数は数値ならARG(:0,1,2...)、文字列ならARGS(:0,1,2...)
関数中で#DIM、#DIMSを用いて定義したプライベート変数も引数に指定可能
呼び出し側
CALL (関数名),(引数1),{(引数2)....}
数値は数式または文字列式が使用できます。\\
文字列リテラル(定数)を引数にするときは""でくくってください。\\
書式付の文字列リテラルを引数にするときは@"〜〜"で書いてください。\\
CALL以外にJUMP、CALLFORM、TRYCALLなどでも同じ書式が使えます。\\
関数側の引数はいくつでも指定できます。\\
ver1.808現在、関数側と呼び出し側で型が異なる場合、数値から文字列、文字列から数値に関わらず変換せずエラーになります。\\
ver1.807以前と同様に文字列型の引数に数値を与えて呼び出したい場合、コンフィグ設定を変更するか、TOSTR関数を用いてください。\\
引数は省略できます。省略した場合、数値型の場合は0、文字列型の場合は空文字列が代入されます(初期値を設定していない場合)。\\
呼び出された関数側ではARGとARGSで渡された値を参照できます\\
基本的に値渡しなのでARGの中身を変更しても渡した元の変数等の値は変化しないことに注意してください。\\
ARGやARGS、または関数中で#DIM、#DIMSを用いて定義したプライベート変数以外の変数(AやSTR)を引数にすることも可能ですが、いくつか制限があります。\\
ver1.808現在、これらの変数を用いた場合は初期値を設定できず、また引数を省略できません。\\
;定義
@FOOBAR, ARG:0, ARGS:0
〜〜
@HOGEHOGE, ARG:0, ARG:1, ARG:2
〜〜
;呼び出し
;変数で指定
CALL FOOBAR, X , STR:0
;定数で指定
CALL FOOBAR, 123 , "あいう"
;書式付文字列で指定
CALL FOOBAR, 123 , @"[{COUNT}] あいう"
;式で指定
CALL FOOBAR, X + 10, "あいう" * 10
;引数の省略-全部
CALL FOOBAR
;引数の省略-第1引数
CALL FOOBAR, , "あいう"
;引数の省略-第2引数
CALL FOOBAR, 123
<エラーになる例>
;エラー(引数が多すぎる)
CALL FOOBAR, X , STR:0, Y
;エラー(引数の型が違う-数値型の第1引数に文字列を代入しようとしている)
CALL FOOBAR, "あいう", "かきく"
;エラー(引数の型が違う-文字列型の第2引数に数値を代入しようとしている)
CALL FOOBAR, 123 , 456
<動作はするが推奨されない例>
;代入先はARG、ARGSでなくても可能ですが、通常はARGを使うことを推奨します
@FOOBAR, X, Y
;代入先を可変にすることも可能ですが可読性が下がります。
@FOOBAR, ARG:X, ARG:Y
;可読性が下がります。
@FOOBAR, ARG:0, ARG:(ARG:0)
==== 引数の初期値 ====
関数の引数に初期値を設定することができます。\\
初期値を設定する場合、関数側は以下のようになります。\\
@(関数名),(引数1 = 初期値1),{(引数2 = 初期値2)....}
引数は数値ならARG(:0,1,2...)、文字列ならARGS(:0,1,2...)、
または関数中で#DIM、#DIMSを用いて定義したプライベート変数
それ以外を指定した場合初期値は設定できません。
指定可能な初期値は定数および定文字列のみで、変数は指定できません。\\
また文字列の初期値は""でくくってください。\\
初期値を設定し、呼び出し側が引数を省略した場合、初期値に設定した値が代入されます。\\
省略せずに関数を呼び出した場合は、通常通りARGとARGSに渡された値が代入されます。\\
;初期値設定(部分省略もできます)
@FUNCTION, ARGS:0 = "かきく", ARG:0 = 111, ARG:1, ARG:2 = 200
〜〜
;エラー(初期値は定数および定文字列のみ)
@FOOBAR, ARG:0 = MASTER, ARG:1 = TARGET
;ARG、ARGS,関数中で#DIM,#DIMSを用いて定義したプライベート変数以外の引数に初期値を設定しても無視されます。
;そのため想定通りの動作ができません。
@FOOBAR, X = 5, Y = 4
==== 引数の参照渡し ====
ver1.810から、参照型変数を仮引数にすることで引数の参照渡しができるようになりました。\\
参照型変数の定義方法は[[erabasicリファレンス_変数・定数・配列#変数の宣言・有効範囲|参照型変数の項]]を確認してください。\\
<実行結果>
A == 100
B == 100
上の例で関数TESTは仮引数に参照型変数を持ちます。\\
1回目にTESTが呼ばれたとき、HOGEは実引数Aを参照するようになります。\\
関数TEST中でHOGE = 100とすることで参照先の変数Aに100が代入されるので1回目のPRINTFORMLの結果は100になります。\\
同様に2回目のTESTが呼ばれると変数Bに100が代入され、2回目のPRINTFORMLの結果も100になります。\\
===== 属性 =====
関数の仕様や動作を決定するプリプロセッサです。\\
関数に#から始まるプリプロセッサを記述する場合、関数の直下にしなくてはなりません。\\
===== #ONLY =====
イベント関数専用の属性です。\\
X = GET_CFLAG(TARGET, Y)
STR = %GET_NAME(TARGET)%
@GET_CFLAG(ARG:0, ARG:1)
#FUNCTION
SIF ARG:0 <= 0 || ARG:0 >= CHARANUM
RETURNF 0
RETURNF CFLAG:(ARG:0):(ARG:1)
@GET_NAME(ARG:0)
#FUNCTIONS
SIF ARG:0 <= 0 || ARG:0 >= CHARANUM
RETURNF ""
RETURNF NAME:(ARG:0)
※関数定義の引数を()でくくっていますが、これは定義の場合は必須な文法ではありません。\\
式中関数を呼び出す場合は()でくくった文法を用いる必要があります。\\
通常の関数と同様に関数名と引数をカンマでわけることもできます。\\
以下の2行は同じ意味です。\\
@GET_CFLAG(ARG:0, ARG:1)
@GET_CFLAG, ARG, ARG:1
また、引数に初期値を設定することができます。\\
初期値についての文法は自作関数における引数指定をご覧ください。\\
==== 制限 ====
=== CALLから呼び出せない ===
FUNCTION(S)フラグを付けた関数はCALLなど通常の呼び出しはできません。\\
式中でのみ呼び出せます。\\
;エラー
CALL GET_CFLAG, X, Y
@GET_CFLAG(ARG:0, ARG:1)
#FUNCTION
SIF ARG:0 <= 0 || ARG:0 >= CHARANUM
RETURNF 0
RETURNF CFLAG:(ARG:0):(ARG:1)
IF X || GET_ASSI_CFLAG(0)
Y = CFLAG:ASSI:2
ENDIF
@GET_ASSI_CFLAG(ARG:0)
#FUNCTION
SIF ASSI < 0
ASSI = 0
RETURNF CFLAG:ASSI:(ARG:0)
一見すると Y = CFLAG:ASSI:2 の実行時に ASSI < 0 になることはないように見えます。\\
しかし、X が0でない場合は短絡評価によりGET_ASSI_CFLAGが実行されないため、ASSI < 0のままCFLAG:ASSI:2を評価しようとしてエラーになる場合があります。\\
式の評価順により結果が変わる\\
式中での変数・関数の評価順は不定です。\\
副作用のある関数は式の中の関数がどの順番で呼び出されるかに依存する場合があります。\\
そのようなコードを書かないでください。\\
呼び出し順はEmueraのバージョンが同じであれば同じになるでしょうが、将来変更されるかもしれません。\\
下のスクリプトでは、ADDCHARA_CFLAG中でTARGETを変更しています。\\
X = CFLAG:TARGET:10 + ADDCHARA_CFLAG(0)
@ADDCHARA_CFLAG(ARG)
#FUNCTION
ADDCHARA ARG
TARGET = CHARANUM -1
RETURNF CFLAG:TARGET:2
ADDCHARA_CFLAGより前にCFLAG:TARGET:10を評価するか、後でCFLAG:TARGET:10を評価するかによってCFLAG:TARGET:10の指す変数が変わってきます。\\
したがってこのスクリプトは評価順に依存します。\\
FUNCTION(S)フラグを付けた関数の中でADDCHARAやTARGETへの代入をすべきではありません。\\
デバッグ用の機能により呼び出されることがある\\
FUNCTION(S)フラグを付けた関数は*.ERBファイル中のスクリプトからだけではなく、デバッグコマンドやデバッグ用の変数ウォッチウインドウから動的に呼び出されることがあります。\\
特に変数ウォッチは頻繁に値を更新しようとし、更新のたびにその関数を呼び出します。\\
副作用を持つ関数はこのような呼び出しにより誤動作を起こす可能性があります。\\
===== 命令の説明 =====
==== CALL 関数名(,引数変数,…) ====
関数呼び出し命令です。関数名の関数を呼び出しますが、なければエラーになります。RETURN命令もしくは関数の終端で元のCALL命令の次の行に戻ります。そのときにRESULT:0にRETURN命令で入れられた数値が入ってます
==== JUMP 関数名(,引数変数,…) ====
関数移動命令です。関数名の関数がなければエラーを出します。あればそこに移動します。移動したら元の場所には戻って来ません。
==== THROW