HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2014
0516
もーとくん#deffunc の使い方6解決


もーとくん

リンク

2014/5/16(Fri) 15:37:27|NO.62020

こんにちは、hsp初心者です。
サンプルソースを理解しながら、いじくっては遊んでいます。
さて質問ですが


cls pos 20,20 :color 0,0,255 :font msgothic,18,1 mes "青文字" pcfm "赤文字",255 #deffunc pcfm str moj,int c1 pos 20,50 :color c1,0,0 :font msgothic,18,1 mes moj return

と打ち込みますと、実行時に成功はしているのですがエラーがでます。
やりたいことはなんとなく分かっていただけると思います。どこが悪いのでしょうか。
変数のどこかが悪いみたいなんですが、定義していないから?

回答よろしくお願いします。



この記事に返信する


fortunehill

リンク

2014/5/16(Fri) 16:19:36|NO.62021

/*ご参考(モジュール化されて居ないので名前空間の問題でエラーが出ます)*/

cls pos 20,20 :color 0,0,255 :font msgothic,18,1 mes "青文字" pcfm "赤文字",255 stop ;(追加) #deffunc pcfm str moj,int c1 pos 20,50 :color c1,0,0 :font msgothic,18,1 mes moj return



もーとくん

リンク

2014/5/16(Fri) 18:14:50|NO.62027

即急な回答ありがとうございます。"stop"だけだったんですね。
ただ原因について、

>>モジュール化されて居ないので名前空間の問題でエラーが出ます

とのことですが、モジュール化、名前空間、
どちらも調べてみたのですが、難しくて理解できませんでした。(分割?衝突?)
"stop"で2つに分けたということですか?

原因理解不明のままだと、今後このような問題が起きたときにまた謎になります。
しつこいようですが、モジュール化、名前空間と今回の原について
初心者の私にでもわかるように説明していただけませんでしょうか。



cats

リンク

2014/5/16(Fri) 21:16:50|NO.62032

#deffuncでは一連の流れを新しい関数(命令)として登録することができます。
#deffunc〜return は #module〜#global で囲ってください。

#module #deffunc pcfm str moj, int c1 pos 20, 50 :color c1,0,0 :font msgothic,18,1 mes moj return #global cls pos 20,20 :color 0,0,255 :font msgothic,18,1 mes "青文字" pcfm "赤文字",255
自分で関数を登録するというのは非常に便利で、
確実に必要な知識です。
「HSP モジュール」で調べるとこの#module,#deffuncなどを使った
プログラムがたくさんあるので、それを見て勉強してみてください。
↓影付き文字モジュールの例

#module #deffunc smes str string_ px=ginfo(22) : py=ginfo(23) //現在posで指定されている位置 r=ginfo(16) : g=ginfo(17) : b=ginfo(18) //現在colorで指定されている色 color //影の色 pos px+2, py+2 : mes string_ //影の文字表示 color r, g, b //元の色 pos px, py : mes string_ //元の文字表示 return 0 //とりあえず0を返す #global color 255 smes "Hello, world!" stop



FunnyMaker

リンク

2014/5/16(Fri) 22:05:11|NO.62034

モジュール化、名前空間について少し説明します。
あくまで私の見解で、絶対正しいとは自信を持って言い切れませんので、間違い等あるかもしれません。
詳しくは、「HSP3モジュール機能ガイド」という文書がHSPのパッケージに同梱されているのでそちらをみてください。

「モジュール化」というのは文字通り「モジュール」にすることですが、そもそもHSPにおけるモジュールとは、
「名前空間」で分割された「部分」のことです。
「名前空間」という言葉が出てきましたね。"空間"と聞くと三次元空間をイメージしがちですが、ここでの空間はそういったものではなく、
概念的なものです。数学で言う「集合」のような存在です。
HSPのプログラムはすべてなんらかの名前空間に属しています。デフォルトでは「hsp」という名前空間に属しています。これをグローバル空間と言うそうです。
ある名前空間「name」に属する定数・変数,命令の正式名称は「@name」がついたものです。
例えばエディタを起動してただ mes "3" と記述すれば、「mes」のフルネームは「mes@hsp」なのです。
(※変数の場合は「hsp」という名前空間には居ないようです。「a」と「a@hsp」は区別されます。ここらへんは私にはよくわかっていません。)
なんでフルネームで呼ばなくてもOKなのかということについてですが、それは、ある空間内のコード中で空間の名前を省略した場合、
コンパイラにより後に自動で補完されるからです。
ですから、最終的にはやはりフルネームで呼ばれています。コンピュータの原則は一意性ですから、あいまいさは許されないわけですね。
ただ、人間は「文脈」が読めますから、分かり切った名前空間名をわざわざ記述するという手間のかかることをしたくない(せずとも正しく読める)わけで、
エディタの中では省略できるように設計されているのです。
(ちょうど、全国チェーン店Xがあるとして、A県にいる人同士の会話でA県のX店を指すときに、特に理由もなくわざわざ「"A県の"X店に行こう」ということはないし、
そんなことをしなくてもちゃんと会話が成り立つのと同じイメージです。)


名前空間は自分で新たに作ることもできます。それを可能にするが「#module」と「#global」というコードです。
この二者に挟まれた部分は別の名前空間に属します。
例えば

a = 1 #module hoge a = 2 #global
(※このコードは実行しても意味を成しませんが、ここでは話をわかりやすくするためにあえてツッコミはなしで。)
においてグローバル空間に属する「a」とhoge空間に属する「a」は違います。両者には正式名称があり、それぞれ「a@」,「a@hoge」です。
ある空間から別の空間の中の定数・変数や命令を呼び出すには、ちゃんとフルネームで呼んであげる必要があります。
例えば、

#module hoge #deffunc func_hoge a = 2 return #global func_hoge mes a@hoge
(#deffuncが出てきましたが、後に説明します。ここでは深く考えず、hoge空間のaに2を代入する作業のためのものだと思ってください。)
というコードで、グローバル空間からhoge空間のaを参照しています。ただ「a」と書くだけではだめです。それだと、a@が参照されてしまいます。

#module〜#globalは放っておいて実行されるものではありません。

#module hoge a = 2 #global mes a@hoge
こうすると、2が表示されそうな気がしますが、そうではありません。モジュールは呼び出してやらないと何もしません。空間ですから。動くものを中に入れないと意味がありません。
モジュールはラベルとは違いますので、単純に上から実行されるわけではないのです。もう少し言うと、どの位置においても普通は差し支えないということです。

そこで、#deffuncを使って新規命令(動くもの)を名前空間(すなわちモジュール)中に作り出すわけです。
#deffuncの使い方はここで述べられるほど単純ではないので、HSPのヘルプを参照してもらうことにし、説明は割愛させてもらいます。
ただ、述べておきたいこととして、どうやら、#deffuncはラベル的な構造になっているようです。最後にreturnがあることからも察しがつきます。
というわけで、質問者さんのスクリプト

cls pos 20,20 :color 0,0,255 :font msgothic,18,1 mes "青文字" pcfm "赤文字",255 #deffunc pcfm str moj,int c1 pos 20,50 :color c1,0,0 :font msgothic,18,1 mes moj return
では、#deffuncで作られたラベル的な部分が、pcfmで1回実行され、returnでpcfmの直後に戻ってきます。(サブルーチンみたいですね。このイメージは大事です。)
その後、下へ向かってコードが実行され、2回目に突入します。その時は「呼ばれていない」つまり#deffuncによって成されるはずの作業が行われないままラベルの中身が実行されるので、
mojやc1といったものが何を指すのかが定まらないまま、直後の color で参照されることにより、エラーになってしまうということです。
pcfmの直後にstopを入れたからと言って「空間が2つに分かれる」のではなく、単に2回目の実行を防止しているだけなのです。

先ほど、「モジュールは呼ばないと動かない」と言いましたが、このことを利用すると、質問者さんのスクリプトは次のように改良できます。


cls pos 20,20 :color 0,0,255 :font msgothic,18,1 mes "青文字" pcfm "赤文字",255 #module mod_pcfm #deffunc pcfm str moj,int c1 pos 20,50 :color c1,0,0 :font msgothic,18,1 mes moj return #global
1度はpcfmによって呼ばれ、returnでpcfmの直後に戻ってきますが、コードが下へ向かって実行される原則のもとでも、
モジュールmod_pcfmは「呼ばれていない」ので、2度目の実行は起こらないということです。


以上、長々とした説明になってしまいました。お役に立てれば幸いです。



きのよー

リンク

2014/5/17(Sat) 18:49:12|NO.62050

モジュール化を簡単に説明すると、部屋をパテーションで区切るような感じです。
区切らずに誰かの名前を叫ぶと、もしかしたら同じ名前の人が二人反応するかもしれませんが、パテーションで区切ると区切られた中の人しか反応しませんよね?
それと同様で、変数名やラベル名が書かれた部屋(つまりスクリプト)を、仮想のパテーションのようなもので区切ることをモジュール化と言います。
ただし、部屋を完全に分けてしまってはパテーションの目の前で動作が止まってしまうので、部屋の中に小さな部屋を作るような形で想像すれば、そのパテーションの向こう側に行けますね。
したがって、パテーションで区切らなければすべてのコードを読み込んでしまい、逆にパテーションで区切ればその中と外で動作や変数が別になるということです。
では、パテーションで区切った中の人を呼び出したいときにはどうすればいいのかというと、
「○○パテーションの中の□□さん」といったような呼び方をすれば必ず反応しますね。
FunnyMakerさんが完璧にご紹介なさっていますが、コンパイルするときには必ずこの呼び方に統一されています。
つまり、自動的に名前だけでどこのパテーションの中にいる人かを判別してくれているのです。
私はこのような考え方で理解をしているので、ご参考までに。

ちなみに、拡張命令などを読み込むとき#include命令を使いますが、これは単にファイルの中をそこにひっつけているだけなので、ASファイルなどの中は必ずと言っていいほど#moduleで囲まれていると思います。
逆にコードの長さが尋常じゃなくなってファイルを分けたくなった時は、#moduleを使わず#includeで読みこめば続けて実行してくれますよ。



もーとくん

リンク

2014/5/19(Mon) 00:13:38|NO.62109

遅れました。

なかなか難しいですが、 何度もよむうちになんとなく理解できました。
ありがとうございます



ONION software Copyright 1997-2021(c) All rights reserved.