また今更ながらのネタかもしれませんが、
moduleの配列について。
moduleは、オブジェクト指向でいうクラスみたいなものだと認識していますので
その配列は、かなり頻繁に使います。
作りたいものがあって、作ろうと思ったら
たぶんすぐ出会う。(実際出会った。)
そこで、HSPのヘルプを見ていたら、
便利機能が書いてあったので、サンプルを作ってみました。
--------
; moduleの配列について
goto *main
; IDを覚えてるだけのmodule
#module myMod n_id
#modinit int p_num
n_id = p_num
return
#modcfunc local GetId
return n_id
#global
*main
; module生成3連発
newmod aMyMod, myMod, 111
newmod aMyMod, myMod, 222
newmod aMyMod, myMod, 333
; aMyModは配列になっているので、そのつもりでmes
len = length(aMyMod)
for i, 0, len
mes "[" + i + "] ID=" + GetId@myMod( aMyMod( i ) )
next
stop
------------
newmodのところで、オブジェクト指向的には(しつこい?)クラスをnewしているわけです。
newしているんだけど、aMyModという同じ変数に入れ続けているのがポイントです。
newmodという関数は、
1つ目の引数がmodule型でない場合は、module型に初期化して設定。
module型の場合は、配列変数として新しい要素を追加する。
という仕様なのです。
すばらしいです。
HSPの配列は、値を保ちながら要素を増やすことができないので
newmodの中で勝手にやってくれるのは歓迎です。
もし嫌なら、別の変数を用意してやればいいわけだし。
そんな備忘録でした。
あ、処理結果。
[0] ID=111
[1] ID=222
[2] ID=333
今更ですが、配列要素の増減について。。
コトは単純で、dimをもう一度やればいいだけです。
注意点は、元の値はすべて消えるということです。
そうとわかっていれば、対応のしかたもあるということで。
-----
goto *Main
; 関数:配列要素を表示する
#module
#deffunc showArray array ary
mes "要素数:" + length(ary)
for i, 0, length(ary)
mes "[" + i + "] " + ary(i)
next
return
#global
*Main
dim a, 3
a(0) = 1
a(1) = 2
a(2) = 3
showArray a
dim a, 5
a(3) = 4
a(4) = 5
showArray a
dim a, 4
a(3) = 6
showArray a
stop
------
ま、単純なサンプルでした。
結果はこちら。
要素数:3
[0]1
[1]2
[2]3
要素数:5
[0]0
[1]0
[2]0
[3]4
[4]5
要素数:4
[0]0
[1]0
[2]0
[3]6

コトは単純で、dimをもう一度やればいいだけです。
注意点は、元の値はすべて消えるということです。
そうとわかっていれば、対応のしかたもあるということで。
-----
goto *Main
; 関数:配列要素を表示する
#module
#deffunc showArray array ary
mes "要素数:" + length(ary)
for i, 0, length(ary)
mes "[" + i + "] " + ary(i)
next
return
#global
*Main
dim a, 3
a(0) = 1
a(1) = 2
a(2) = 3
showArray a
dim a, 5
a(3) = 4
a(4) = 5
showArray a
dim a, 4
a(3) = 6
showArray a
stop
------
ま、単純なサンプルでした。
結果はこちら。
要素数:3
[0]1
[1]2
[2]3
要素数:5
[0]0
[1]0
[2]0
[3]4
[4]5
要素数:4
[0]0
[1]0
[2]0
[3]6
XMLでやりたいことがあるのですが、
ググッてもなかなかヒットできないことがありました。
それは、要素を取得したときのエラーケース。
XMLで、省略可能な属性を使いたいけども、
その属性を読もうとして、ない場合にどうしたらいいか、です。
数時間格闘した結果、わからなかったので、
HSP.tvの掲示板で聞いたら、すぐに教えてもらえました。その記事
記事の文面と同じですが、こちらにも載せておきます。
★の部分です。
-----
newcom oDom, "Microsoft.XMLDOM"
oDom("async") = 0
// XMLデータ
sdim strXML, 1024
strXML = {"<AAA>
<BBB ccc=\"c1\" ddd=\"d1\" />
<BBB ccc=\"c2\" />
<BBB ccc=\"c3\" ddd=\"d3" >
test
</BBB>
</AAA>"}
oDom->"loadXML" strXML
oRoot = oDom("documentElement")
oNodesOf_AAA = oRoot("childNodes")
nAAANodesNum = oNodesOf_AAA("length") // ノードの数
// 全データを表示
for i, 0, nAAANodesNum
// itemを1つget
oNode_BBB = oNodesOf_AAA("item", i)
// attributesをget
oAtrsOf_BBB = oNode_BBB("attributes")
// attribute ccc をget
oAtr_ccc = oAtrsOf_BBB("getNamedItem", "ccc")
mes "[" + i + "]nodeValue ccc = " + oAtr_ccc("nodeValue")
// assert
// ★attribute ddd をget
oAtr_ddd = oAtrsOf_BBB("getNamedItem", "ddd")
if( varuse(oatr_ddd) = 0 ){
mes "[" + i + "]nodevalue ddd なし"
}else{
mes "[" + i + "]nodeValue ddd = " + oAtr_ddd("nodeValue")
}
next
delcom oDom
stop
-----
このケースでは、BBBタグ内の、ddd属性が必ずしもあるとは限りません。
if文なしで実行すると、oAtr_ddd("nodeValue")のところで、
そんな操作できません的なエラーが出ます。
オブジェクトがNULLなんだから当たり前です。
null pointer exception いわゆるヌルポです。(たぶん
上記のとおり、varuse()関数を使うと、NULLかどうかが判断できました。
ところで今更ながら、
assertという機能を使って、デバッグ実行できることに気づきました。
普段仕事では、C++の開発でVisualStudioを使っているので、
それに比べればまどろっこしいところはあるけども、
ないよりはだいぶましです。
assertは、VisualStudioでいう、ブレイクポイント。
NULLになってるということも、これで気づくことができました。
ググッてもなかなかヒットできないことがありました。
それは、要素を取得したときのエラーケース。
XMLで、省略可能な属性を使いたいけども、
その属性を読もうとして、ない場合にどうしたらいいか、です。
数時間格闘した結果、わからなかったので、
HSP.tvの掲示板で聞いたら、すぐに教えてもらえました。その記事
記事の文面と同じですが、こちらにも載せておきます。
★の部分です。
-----
newcom oDom, "Microsoft.XMLDOM"
oDom("async") = 0
// XMLデータ
sdim strXML, 1024
strXML = {"<AAA>
<BBB ccc=\"c1\" ddd=\"d1\" />
<BBB ccc=\"c2\" />
<BBB ccc=\"c3\" ddd=\"d3" >
test
</BBB>
</AAA>"}
oDom->"loadXML" strXML
oRoot = oDom("documentElement")
oNodesOf_AAA = oRoot("childNodes")
nAAANodesNum = oNodesOf_AAA("length") // ノードの数
// 全データを表示
for i, 0, nAAANodesNum
// itemを1つget
oNode_BBB = oNodesOf_AAA("item", i)
// attributesをget
oAtrsOf_BBB = oNode_BBB("attributes")
// attribute ccc をget
oAtr_ccc = oAtrsOf_BBB("getNamedItem", "ccc")
mes "[" + i + "]nodeValue ccc = " + oAtr_ccc("nodeValue")
// assert
// ★attribute ddd をget
oAtr_ddd = oAtrsOf_BBB("getNamedItem", "ddd")
if( varuse(oatr_ddd) = 0 ){
mes "[" + i + "]nodevalue ddd なし"
}else{
mes "[" + i + "]nodeValue ddd = " + oAtr_ddd("nodeValue")
}
next
delcom oDom
stop
-----
このケースでは、BBBタグ内の、ddd属性が必ずしもあるとは限りません。
if文なしで実行すると、oAtr_ddd("nodeValue")のところで、
そんな操作できません的なエラーが出ます。
オブジェクトがNULLなんだから当たり前です。
null pointer exception いわゆるヌルポです。(たぶん
上記のとおり、varuse()関数を使うと、NULLかどうかが判断できました。
ところで今更ながら、
assertという機能を使って、デバッグ実行できることに気づきました。
普段仕事では、C++の開発でVisualStudioを使っているので、
それに比べればまどろっこしいところはあるけども、
ないよりはだいぶましです。
assertは、VisualStudioでいう、ブレイクポイント。
NULLになってるということも、これで気づくことができました。