【症状】
現在なでしこでは誤動作防止の為に"ネームスペース"が実装されていますが
これをコーディングスタイルとして利用出来るようにして欲しいです。
【再現方法】
なでしこには"取り込む"という命令があります。
この命令を使えば、外部ファイルのなでしこスクリプトをロードする事が可能です。
この場合、取り込むを使ってロードされたスクリプト内に
取り込んだ側のスクリプトと同じ名前の変数、関数、定数が存在した場合は
別名前空間の物として区別することが出来ます。
関数や変数を参照する時は、[ファイル名]:[変数/関数/定数]とすることで
名前空間を指定して取得、実行出来ます。
ただ、ここで問題があります。
取り込む命令を利用した側の名前空間も"ファイル名"で決められてしまうのです。
何が問題かというと、この場合取り込まれた側のソースからは
取り込んだ側の名前空間にある情報を確実に利用出来ないのです。
なでしこスクリプトは任意のファイル名で保存出来ます。
今回は"MyApplication.nako"として自作のプログラムを作成し、
"MyApplication.nako"は"Library.nako"を内部で取り込んでいると仮定します。
これ("MyApplication.nako")を実行ファイルに(PACKFILE)した時に、強制的に
"nadesiko.nako"として梱包されてしまいます。
今まで取り込んだ側は 名前空間"MyApplication"を指定して取り込み元の
情報を利用していたため、情報を取得できなくなってしまいます。
先ほど書いたように、なでしこは全ての名前空間をファイル名で扱っています。
そのため実行ファイル化し、ファイル名が"nadesiko.nako"になってしまうと
今までのファイル名("MyApplication")で名前空間を決めうちしていた
ソースは動かなくなってしまいます。
それを避けるために作られたと思われる"ネームスペース変更"命令は
現在動作していません。
現在でも任意のファイル名ではなく"nadesiko.nako"として作成すれば
この問題は回避できますが、これはいかんせん綺麗な対処法ではないと思うのです。
【要望】
名前空間系処理の改善。
とりあえず、私が思いついた改善案を書いておきます。
1.取り込む側の名前空間を強制的に"ユーザー"にする。
これが一番スマートな解決策だと思います。
2.PACKFILE時に"nadesiko.nako"にリネームせずそのまま梱包する。
ファイル名とかで問題が起きそうなので良くないとは思われますが
変更の作業量が少ないとは思います
調査したことのまとめ&軽くメモ。
取り込んだファイルのネームスペース作成の所で、
hima_system.pas THiSystem.ImportFile (l.1549):
Namespace.CreateNewSpace(f.Fileno);
となっている。一方で「ネームスペース変更」命令で渡された引数の Namespace を検索するのには tangoId を使っている。そのため、どうやってもそのネームスペースが存在しないことになってしまっている(たまたま"存在"することは…ほとんどないと思う)。
そこで簡易(*)修正案:
Namespace.CreateNewSpace(hi_tango2id(FName));
のようにすれば、"『Library.nako』にネームスペース変更"と正常に使える。
簡易(*) … 「ネームスペース変更」命令の引数はファイル名「Library.nako」にすべきか接頭辞「Library」にすべきか。どちらが良いか分からなかったし、どちらにしても細かいことするのが面倒(本音)だったからそれ以上試していない。(それぞれ、接頭辞の場合はパスと拡張子を除く処理が、ファイルの場合はパスの展開とかの処理が必要になる)
----
直接本件とは関係ありませんが、条件コンパイルが一部上手く行ってないですね。{$ELSE}側が空気になってるみたい(?)です。(通常版用の doAngou6() が {$ELSE} 内で定義されているハズなのに、 doAngou6 が未定義と怒られる。)
念のためにこちらにも進捗状況を書いておきます。
Cf. http://www.undefin.net/nadesiko/commit/2010/0221
!Sにネームスペース変更
ならちゃんと動くので、普通の「ネームスペース変更」命令は不要ではないか?
対処案:
* システム命令「ネームスペース変更」(ID244)の削除
* システム命令登録 AddFunc(...) を消す。
* 不要になるので sys_namespace_change も削除。
* 宣言命令「ネームスペース変更」の登録。
* 予約語登録されていないので Reserve(...) するということ。
* ID244はこちらに振る。
* マニュアルなどには、「ネームスペース変更」は宣言命令であると明記する
> !Sにネームスペース変更
> ならちゃんと動くので、普通の「ネームスペース変更」命令は不要ではないか?
確かに、不要です。
そして、そもそも、動いていなかったのですから、この際、不要な命令は削除してしまいましょう!
>対処案:
> * システム命令「ネームスペース変更」(ID244)の削除
> * システム命令登録 AddFunc(...) を消す。
> * 不要になるので sys_namespace_change も削除。
> * 宣言命令「ネームスペース変更」の登録。
> * 予約語登録されていないので Reserve(...) するということ。
> * ID244はこちらに振る。
> * マニュアルなどには、「ネームスペース変更」は宣言命令であると明記する
以上、問題ありません!
よろしくお願いします
「ネームスペース変更」を命令からプリプロセス宣言へ修正。 (r226)(@460)
http://code.google.com/p/nadesiko/source/detail?r=226
こんにちわ、修正お疲れ様です。
さっそく使ってみたのですが、どうやら取り込まれる側で
ネームスペース変更命令を行うと正常に動作しないようです。
/*Main.nako*/
#ここから
!`Sub.nako`を取り込む
TEST:Aをいう
TEST:Bをいう
#ここまで
/*Sub.nako*/
#ここから
!`TEST`にネームスペース変更//`TEST.nako`としても結果は同じ
!A=`テストです。Aです。`
B=`テストです。Bです。`
#ここまで
これらを同一のフォルダに別ファイルとして保存し、
Main.nakoを実行しても、TEST名前空間内が参照されなく、そのまま
"A","B"と表示されてしまいます。
ただ"ネームスペース変更"命令をSub.nako側に書かなければ
従来通り自身のファイル名で名前空間を参照することはできます。
バグだと思うのでとりあえず報告しておきます。
これでどうでしょう?
/*Main.nako*/
#ここから
!`Sub.nako`を取り込む
!`TEST`にネームスペース変更
Aを表示
Bを表示
#ここまで
/*Sub.nako*/
#ここから
!`TEST`にネームスペース変更
!Aとは文字列=`テストです。Aです。`
Bとは文字列=`テストです。Bです。`
#ここまで
本当は仕様を明文化してマニュアルとかに記述したいけど、自分もまだ明確に理解できていないorz