global local @命令関数の自作 スコープ

 

定数や定義のスコープ
規模の大きいプログラムでは、複数のファイルに分けてプログラムを書いていきます。
膨大なプログラムの中で、命令、関数、変数を重複せずに名前を付けることは厳しい要求です。
モジュールを定義すると、#moduleから#globalまでの間に書いたプログラムは基本的にモジュール名のグループに属し、外部モジュールから見ることができるのは既定で命令と関数のみになります。
そこで、モジュールの中で定義した定数などは、他のモジュールから参照できるようにglobalというキーワードが用意されています。
#const global 定数名 (値)

定数のスコープ
//sample1モジュール//////////////////////////////////////////
#module sample1

#const _TEISU	(3)	//sample1だけの_TEISUを定義
#const global TEISU	(5)	//どこからでも見れるTEISUを定義

#global

//sample2モジュール//////////////////////////////////////////
#module sample2

#const _TEISU	(4)	//sample2だけの_TEISUを定義
;#const global TEISU	(5)	//【エラー】(※1)

#global

//外部モジュール//////////////////////////////////////////////
mes _TEISU	//・・・0(モジュール内の定義は参照できない)
mes TEISU	//・・・5(グローバルにするとはどこからでも参照できる)

定数や定義は実際にそのマクロ名が使われる前に定義しておく必要があります。
(※1)既にsample1モジュール内でグローバル定義済のためエラーが出ます。


 

変数のスコープ
モジュール内で宣言した変数は、表には見えていませんが、変数名「@」モジュール名という形で表現されます。
定数や定義と異なり、モジュール内で宣言した変数をグローバルにする方法はありません。代わりに命令や関数を用意してモジュール内の変数を操作することで実現できます。

変数のスコープ
//sample1モジュール//////////////////////////////////////////
#module sample1
#deffunc Init1
	dim a	//a@sample1(※1)
return 

#deffunc Test1 int b, local c	//(※2)
	dim a	//a@sample1(※1)
return
#global

//sample2モジュール//////////////////////////////////////////
#module sample2
#deffunc Init2
	dim a	//a@sample2(※1)
return

#deffunc Test2 b, local c	//(※2)
	dim a	//a@sample2(※1)
return
#global

//無名のモジュール//////////////////////////////////////////////
dim a	//a@(※3)

(※1)モジュール内の命令や関数内で宣言する変数は、モジュール内の命令や関数で共有される変数です。他のモジュール内の同じ名前の変数とは別々の変数となります。
Init1とTest1のそれぞれの命令にある「dim a」は同じモジュール内の変数宣言なので、どちらもa@sample1となります。
Init2とTest2も同様で、どちらもa@sample2となります。ただし、a@sample1とは別です。

(※2)引数名とローカル変数名は、命令または関数内のみで使用する名前ですが、その命令と関数が属するモジュール内で宣言されている共有の変数名は使えません。
すなわち、a@sample1及びa@sample2として既に宣言されている変数aは名付けられません。
(※3)モジュールに属さない場所で変数を宣言すると、「変数名@」となり、無名のモジュールです。


 

異なるモジュールの値を操作する
モジュールごとにプログラムを分けることで、異なるモジュール内に同じ変数名を使ったとしても、それらは別々の変数として扱われるので同じ名前が使用できることになります。その代わりに、相手モジュールの変数に対して何か処理をしたいときは、相手モジュール内で変数を処理する命令を備えておく必要があります。

外部モジュール内の変数を操作する
//sample1モジュール//////////////////////////////////////////
#module sample1
dim a	//a@sample1

//sample1の変数aを返す関数
#defcfunc GetA
return a

//sample1の変数aに代入する命令
#deffunc SetA int val
	a = val
return
#global

//無名のモジュール//////////////////////////////////////////////
dim a	//a@

//以下の書き方はこのモジュールの変数aしか操作できない
a = 123	//a@に234を代入
mes a	//・・・321(a@の内容を表示)

//sample1の変数aを無名のモジュールで操作したいとき
SetA 234	//sample1の変数aに234を代入する
mes GetA()	//・・・234(a@sample1の内容を表示)


ローカル命令とローカル関数
自作した命令と関数にも変数や定数などと同様に名前を付けます。
これらをモジュール内のみで使用する命令や関数の場合は、命令・関数名の前にlocalというキーワードを付けることで外部のモジュールから呼び出されないようにしておくとその命令や関数の名前の重複を防ぐことができます。
localを付けない時は、暗黙的に全てのモジュールから呼び出せるglobalな命令や関数となっています。
#deffunc local 新しい命令名
#defcfunc local 新しい関数名

 
ローカル命令とローカル関数
//sample1モジュール//////////////////////////////////////////
#module sample1

#defcfunc GetTest1
return GetTestSub()	//sample1のGetTestSub関数を呼び出す

#defcfunc local GetTestSub	//sample1に属するのGetTestSub関数
return 3

#global

//sample2モジュール//////////////////////////////////////////
#module sample2

#defcfunc GetTest2
return GetTestSub()	//sample2のGetTestSub関数を呼び出す

#defcfunc local GetTestSub	//sample2に属するのGetTestSub関数
return 5

#global

//外部モジュール//////////////////////////////////////////////
mes GetTest1()	//・・・3
mes GetTest2()	//・・・5

当サイトコンテンツの複写・転載・引用は禁止しております。