資料館/モジュール変数についての私見

Last-modified: 2009-02-26 (木) 12:55:32

HSPのモジュール型変数について

HSPにはモジュール型変数っつーベリーナイスな機能がある。若干特異な書き方をするし、色々便利な要素を60%くらい実装した感じで中途半端な感じは否めないが、JavaとかC++とかがわかる人なら劣化クラス、という表現を使えばわかりやすいか。
なおこのページには、オブジェクト、リファレンスといった、HSPチルドレンには馴染みの無い単語が出てくることがある。わからなかったらこのページは今無理に読む必要はない。オブジェクト指向プログラミングを理解している人なら、「HSPでクラスっぽいものが使えるんだなあ」という感じで読めると思う。わからんけど。

モジュール型変数の機能分析

なお、以下

  • モジュール→クラス
  • モジュール型変数→オブジェクト

という風に読み替えても問題ないと思う。

モジュール型変数のココがすごい(笑)

スコープ

モジュール型変数内、外は別々の空間として扱われ、変数名などが被っても別のモノとして扱われる。変数の明確な宣言が無いHSPにおいて、複数人でプログラミングする際には変数の命名規則を定めなければ地獄が見えるが、モジュール内ならそういったことは起こらない。


例えばモジュールAを使って作られたモジュール型変数a[0]とa[1]は、それぞれにunkoという変数を持つ事ができ、別々の値を持つ事ができる。

コンストラクタとデストラクタをもてる

なお、作成したモジュール型変数の破棄はdelmod命令で行う。

モジュール変数は引数として受け取る事ができる

モジュール変数を処理するモジュール、といったものも作成できる

モジュール型変数のココがイヤーン

名前がわかりにくい

HSPのマニュアルには、モジュールと名のつく機能が三つある

  • モジュール機能
  • モジュール型変数
  • モジュール変数

この、後ろの二つ。ややこしいってレベルじゃねーぞ!
モジュール変数というのは、newmod命令によって作られたいわゆるオブジェクトだ。
モジュール変数というのは、newmodによって作られたモジュール型変数の、メンバ変数のうち、ほかのモジュール型変数と独立しているものを指す。逆に言えば、モジュール型変数のメンバ変数のうち、モジュール変数でない変数は、各モジュールで共用となる。いわゆるstaticな変数的扱いを受ける。

メンバー変数がデフォルトでstatic

モジュール内で使用する変数は、デフォルトでそのモジュールから作られたモジュール型変数全てで共通のモノとなる。各モジュール型変数で別々の変数を持ちたければ、それをモジュール変数として予め定義しておかなければならない。

モジュール変数をpublicに出来ない

モジュール変数は外部から参照できないので、参照用の命令を定義しなければならない。

privateな命令、関数を作成できない

モジュール内部でだけ使用する命令、といったものが作れない。

派生できない

全てのモジュール型変数は、もとになったモジュールの忠実なコピー。

その他

HSP開発wikiのモジュール変数の項目も合わせて読むと良い

簡単なサンプル

キャラクターの名前、HP、攻撃力を管理するモジュールを作ってみたぞ。

モジュール

#module

;----コンストラクタ
	#modinit str _name,int _HP,int _power,int _speed
		name=_name
		HP=_HP
		power=_power
		speed=_speed
	return

;----自分の名前を出力する【命令】
	#modfunc SamplePrintName
		mes "My name is "+name+""
	return
;----自分のHPを出力する【命令】
	#modfunc SamplePrintHP
		mes ""+name+"「俺の体力は"+HP+"だ」"
	return
;----自分の素早さを出力する【命令】
	#modfunc SamplePrintSpeed
		mes ""+name+"「俺の素早さは"+speed+"だ」"
	return


;----自分の名前を返す【命令】
	#modfunc SampleGetName
	return name
;----自分のHPを返す【命令】
	#modfunc SampleGetHP
	return HP

;----指定したキャラクターのHPを比べる【関数】
	#defcfunc SampleBoSHP var player1,var player2
		SampleGetHP player1;指定されたキャラのHP取得
		hisHP=stat

		SampleGetHP player2

		res=0
		if stat<hisHP:res=1
		if stat>hisHP:res=-1
	return res




	#modterm
		mes ""+name+"を破棄"
	return

#global

このモジュールは、キャラクターの名前、HP、攻撃力を管理する。Speedというパラメータは、サンプル用に設けてあるがモジュール変数ではないため、別々の値はもてない。
各々の命令や関数の動作は非常に単純なものばかりなので、チルドレン達も出来ればこの機会にモジュール変数に触れて欲しい。

モジュールを呼び出してみる

	randomize
	dim player,3
	name="リック","カイン","クー"
	repeat 3
		newmod player,playerdata,name.cnt,rnd(10),rnd(10),rnd(10)
	loop


	mes "Player.0の名前を出力させる"
	SamplePrintName player.0;名前を出力させる


;-------モジュール変数にアクセスしようとするとエラーになる-----------
;mes "\nnameはモジュール変数なので、直接アクセスできない:"+name@playerdata+""
;--------------------------------------------------------------------

	mes "\nspeedはモジュール変数ではないので、直接アクセスできる:"+speed@playerdata+""
	mes "speedは各モジュール型変数で共通なので、全員の値は全て同じはず"
	repeat 3
		SamplePrintSpeed player.cnt
	loop

	speed=500
	mes "\nspeedに値を代入しても区別される。"+speed+"/"+speed@playerdata+""

	mes "\nHPはモジュール変数なので、各々異なる値を保持する"
	repeat 3
		SamplePrintHP player.cnt
	loop


	mes "\n\nplayer.0とplayer.1のHPを比較する"
	kekka=SampleBoSHP(player.0,player.1)


	mes kekka
	if kekka>0:{
		mes "player.0のHPの方が多い"
	}
	else:if kekka<0:{
		mes "player.1のHPの方が多い"
	}
	else:{
		mes "二人のHPは等しい"
	}


	delmod player.2;モジュール変数を破棄

上記モジュールを使って色々実験してみた。実際に利用するためには、モジュールの内容をソースコードにコピペするか、別のファイルとして保存しincludeする必要がある。
実行結果はこんな感じになる。
result.jpg

モジュール内で別のモジュールを呼び出したりと、割と使えそうなこともやっているので、是非眺めてみて欲しい。