小ワザ
モジュール変数 †
HSP3から新たに導入されたモジュール系命令の使い方を模索。
みんなでいじってください。
+
| | レポートスクリプト
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
| #module testmod modno,modvalue,body
#modinit
mes "コンストラクタが呼び出されました。"
modcnt ++
return
#modterm
mes "デストラクタが呼び出されました。"
modcnt--
return
#modfunc tm_getcnt var v
v = modcnt
return
#modfunc tm_setvalue int n
modno = modcnt-1
modvalue = n
return
#modfunc tm_dispvalue
mes "mod["+modno+"] = "+modvalue+"("+body.0+","+body.1+","+body.2+")"
return
#modfunc tm_setbody int b, int w, int h
body = b, w, h
return
#global
randomize
font "MS ゴシック",14
repeat 3
newmod m, testmod
tm_setvalue m(cnt), rnd(10)
tm_setbody m.cnt, 80+rnd(3), 59+rnd(3), 82+rnd(3)
tm_dispvalue m.cnt
loop
mes "<< モジュール内(?)の全てのインスタンスを表示 >>"
foreach m
tm_dispvalue m.cnt
loop
mes "配列の確保済み領域:"+length.m
tm_getcnt m, i : mes "インスタンスの数:"+i
mes "mod["+(i-length.m)+"]を削除します。"
delmod m(i-length.m) : mes stat mes "配列の確保済み領域:"+length.m
tm_getcnt m, i : mes "インスタンスの数:"+i
mes "<< 有効なインスタンスの列挙 >>"
foreach m
tm_dispvalue m.cnt
loop
|
|
|
- インスタンス毎に異なる型のメンバを保持できる。
+
| | サンプル
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
| #module test mv01
#modfunc set_str str s
mv01 = s: return
#modfunc set_int int i
mv01 = i: return
#modfunc set_double double d
mv01 = d: return
#modfunc disp_mv
mes ""+mv01+"("+vartype(mv01)+")": return
#global
newmod m, test: set_str m.0, "Hello,world!"
newmod m, test: set_int m.1, 100
newmod m, test: set_double m.2, 1.7320508
foreach m
disp_mv m.cnt
loop
stop
|
|
|
- モジュール内変数はインスタンス間で共有される。
+
| | サンプル
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
| #module test mv01
#modinit
count++
return
#modfunc disp_count
mes count
return
#global
newmod m, test: disp_count m.0
newmod m, test: disp_count m.1
disp_count m.0
stop
|
|
|
- モジュール変数(インスタンス)は引数で受け取れる。
+
| | サンプル
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
| #module modv mv01
#modinit
count++
return
#modfunc get_countx var v
v = count
return
#defcfunc get_count var m
get_countx m, vf
return vf
#global
newmod m, modv: mes get_count(m.0)
newmod m, modv: mes get_count(m.1)
stop
|
|
|
見やすく、わかりやすく、に注意しつつ書いてみました。
もっと見やすく出来るようでしたら修正していただけると助かります。
+
| | サンプル
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
|
|
#module SchoolClass name, age, sex, address
#modinit str _name, int _age, str _sex, str _address
name =_name
age =_age
sex =_sex
address =_address
modcnt++ return
#modterm
mes "" + name + " さんの情報を削除しました。"
modcnt-- return
#modfunc modGetStudent_name
return name
#modfunc modGetStudent_age
return age
#modfunc modGetStudent_sex
return sex
#modfunc modGetStudent_address
return address
#defcfunc modGetStudentCnt
return modcnt
#global
newmod seito, SchoolClass, "三原 貴史", 10, "男", "東京都"
newmod seito, SchoolClass, "柊沢 雪兎", 11, "男", "東京都"
newmod seito, SchoolClass, "大道寺 撫子", 11, "女", "東京都"
newmod seito, SchoolClass, "ジョルジュ長岡", 22, "漢", "にっぽん"
i = 1
delmod seito(i)
if varuse(seito(i)) = 0 : mes "登録削除を確認しました。"
gosub *hyouji
newmod seito, SchoolClass, "柳沢 利佳", 10, "女", "東京都"
pos ginfo_winx/2, 0
gosub *hyouji
stop
*hyouji
mes "全部で "+length(seito)+"人分の情報が登録されています。"
mes "実登録数:"+ modGetStudentCnt() + "名"
mes "-----\n登録情報を出力します。"
foreach seito modGetStudent_name seito(cnt)
name = refstr
modGetStudent_age seito(cnt)
age = stat
modGetStudent_sex seito(cnt)
sex = refstr
modGetStudent_address seito(cnt)
address = refstr
mes "名前 :" + name +"(" + age + ")・"+sex
mes "出身 :" + address
mes "--------------------------------"
loop
return
|
|
|
マニュアルには正式な記載はありませんが、次のようにしてnewmodで作成したモジュール変数の配列番号を取得することが出来ます。
- thismodを使う方法。
+
| | モジュール変数の配列番号を取得
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
| #module
#defcfunc getModuleID var In_module, local Out_ID
mref Out_ID, 1
return Out_ID
#global
#module TestModule ThisID
#modinit
ThisID = getModuleID( thismod )
return ThisID
#global
newmod ModuleVar, TestModule
mes stat
newmod ModuleVar, TestModule
mes stat
newmod ModuleVar, TestModule
mes stat
|
|
|
HSP3掲示板(NO.39717 ひらまる さん)より引用
- mrefの 2を使う方法。
+
| | モジュール変数の配列番号を取得
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
| #module MTest id
#modinit
mref id, 2
return id
#global
max = 5
dimtype mod, vartype( "struct" ), max
repeat max
newmod mod, MTest : id = stat
mes "id = " + id
await 0
loop
|
|
|
HSP3掲示板(NO.39745 xxx さん)より引用
- mrefの 68を使う方法。
+
| | モジュール変数の配列番号を取得
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
| #module
#define prmstack 207
#define global ctype pvalptr(%1) pvalptr_(%1, 0)
#define global ctype getaptr(%1) pvalptr_(%1, 1)
#defcfunc pvalptr_ var _p1, int _p2
mref HSPCTX, 68
dupptr vptr, HSPCTX.prmstack, 8, 4
return vptr(_p2)
#global
#module mv a, b
#modinit
return getaptr( thismod )
#global
newmod v, mv : mes stat
newmod v, mv : mes stat
newmod v, mv : mes stat
newmod v, mv : mes stat
delmod v(2) : mes "delete v(2)"
newmod v, mv : mes stat
newmod v, mv : mes stat
|
|
|
バグトラッキングシステム内のHSP3WishList?35: newmod で追加された添え字を取得したいより naznyark さんのレスポンスから引用
モジュール型変数の要素を削除を削除するには、delmod命令を使用する。
例えばモジュール型変数「v」の要素番号「1」を削除するには次のように記述する。
delmod v(1)
なお、この方法の場合要素番号の把握が欠かせないため、自前でカウントするか上述した方法でモジュール変数の配列番号を取得する必要がある。
また、thismodを活用することで要素番号を意識せずにモジュール型変数の要素を削除することもできる。(※この方法はサンプルやマニュアルに記載が無い手法であることを記しておく。)
+
| | 条件を満たす要素だけを削除
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
|
#module mod_test prm1
#modinit
count++
prm1 = count * 10
mes "set:" + prm1
return
#modterm
mes "削除しました。"
return
#modfunc mod_get
return prm1
#modfunc mod_del int pp
if prm1 = pp : delmod thismod
return
#global
repeat 3
newmod a, mod_test
loop
gosub *disp
foreach a
mod_del a(cnt), 20
loop
gosub *disp
newmod a, mod_test
gosub *disp
stop
*disp
mes "-<内容確認>---------------------------------"
foreach a
mod_get a(cnt)
mes "num("+cnt+"):" + stat
loop
mes "----------------------------------------------"
return
|
|
|
死亡フラグを使ったり、一定のしきい値を超えた場合だけ駆除なとどいったケースでの利用が考えられる。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#module Person name, age
#modinit str _name, int _age
name = _name
age = _age
return
#modfunc getName
return name
#modfunc getAge
return age
#global
;////////////////////////////
#module Student grade, super
#modinit str _name, int _age, int _grade
newmod super, Person, _name, _age
grade = _grade
return
#modfunc getGrade
return grade
#modfunc super_getAge
getAge super
return stat
#modfunc super_getName
getName super
return
#global
newmod Jack, Student,
"Jack",
20,
2 super_getName Jack
super_getAge Jack
getGrade Jack
マニュアルでは不足している情報をここでまとめてみます。
- newmodで追加された添え字を取得する
- 変数の使用状況を調べる
プログラミングマニュアル1・基本仕様ガイド (hspprog.htm) にはmoduse命令を使用するとありますが、2004年に命令が変更になっています。
旧:moduse → 新:varuse
使い慣れない言葉がいくつかありますので、簡単に解説しておきます。(間違いを発見したら修正お願いします。)
なお、単語の中には一般的に他の言語などでも使用される単語がありますが、ここではモジュール変数の説明で使用される単語であるとします。
- モジュール変数(モジュール型変数)
複数の変数やデータをまとめて管理することができる変数。
または、複数の変数やデータをまとめて管理することができるデータ格納方法。(モジュール変数機能)
- インスタンス
直訳すると「実体」。オブジェクトとも。
newmod命令で内容を得たモジュール変数のこと。
- モジュール型 (struct)
モジュールで定義されている型の総称。int や str と同じたぐい。
型の構成は、newmod命令でユーザーが独自に作成することが出来る。
- コンストラクタ
newmod命令でモジュール型変数を作成した際に自動的に実行される処理。
主に、モジュール変数の内容の初期化を行う、などに使用する。
処理内容は#modinit命令で登録できる。
- デストラクタ
モジュール型変数が削除(解放)される際に自動的に実行される処理。
処理内容は#modterm命令で登録できる。
- メンバ変数
モジュール変数の内容のこと。つまり、モジュール変数が保有している複数の変数のこと。
#modfunc、#modinit、#modterm命令の内部からしかアクセスできない。
・単に「メンバ」、とも。
- モジュール命令
#modfunc命令で登録された命令のこと。第一パラメータにモジュール変数を受けとる。
この中からなら、モジュール変数のメンバ変数にアクセスできる。
- モジュール内変数
モジュール内で使用している、モジュール変数の管理外にある共有の変数。
ただ単に、モジュールの中に閉じこめられている通常の変数。モジュール変数機能とはあまり関係ない。
#modfuncなど以外からでもアクセスできる。
<資料>
プログラミング・マニュアル
3.拡張文法
モジュール
■モジュール変数の定義