
本記事は、ネームスペースの切り替えについて解説したいと思います。
はじめに
ObjectScriptでネームスペースの切り替えが分らない方はいないと思いますが、どうやって切り替えていますか?
私が知りうる限りでは、ネームスペースを切り替えるコマンドは4種あります。
※似たような奴が多いな!
この記事では、これらのコマンドをどのようなタイミングで運用すればいいのか、備忘を兼ねて検証したいと思います。
それではさっそく、ObjectScriptでのネームスペース切り替えについてみていきましょう!
各性能
検証する前に、ネームスペース切り替え時に関連するコマンド達を確認したいと思います。
切り替え時に併せて利用するコマンド
ネームスペースを切り替える際に必要なコマンドをまとめました。
現在のネームスペースを取得する
ネームスペースの切り替えの前に、現在のネームスペースを取得するコマンドになります。
4種記載していますが、「$namespace」を使っておけば十分だと思います。
w $namespace // 現在のネームスペースが返る
w $SYSTEM.SYS.NameSpace()
w $znspace
w ##class(%SYS.ProcessQuery).%OpenId($JOB).NameSpaceGet()
ネームスペースが存在しているか確認する
変更先のネームスペースが存在しているか確認するコマンドになります。
$zuはレガシーなので、%SYS.Namespace.clsの関数を使用する方が良いです。
s ns = $namespace
w ##class(%SYS.Namespace).Exists(ns) // 1 が返る
w $zu(90, 10, ns) // 1 が返る
ネームスペースのリストを取得する
現在のプロセスで使用できるネームスペースの一覧を取得するコマンドになります。
→ListAll()で十分ですね。
// 方法1
d ##class(%SYS.Namespace).ListAll(.nsList)
zw nsList
// nsList("%SYS")=""
// ~ 略 ~
// nsList("USER")=""
// 方法2
s stmt=##class(%SQL.Statement).%New()
d stmt.%PrepareClassQuery("%SYS.Namespace","List")
s rset= stmt.%Execute(ListRemote)
while(rset.%Next()){ w rset.%Get("Nsp"),",",rset.%Get("Status"),",",rset.%Get("Remote"),!}
// %SYS,1,0
// ~ 略 ~
// USER,1,0
切り替えコマンド
いよいよネームスペースの切り替えコマンドです。
$namespace
$namespaceを「new」した後、$namespaceに変更後のネームスペース名をセットします。
これを行うことで、スタック・レベル内でのみネームスペース変更が有効になります。
※ラベル「Move」や関数「Sub」の処理内のみ有効となる
そのため、元の処理に戻った際にネームスペースを戻す処理が不要になります。
ClassMethod main()
{
s ^nsDt(1, "start")=1 // 実行ネームスペース
d ..Sub()
s ^nsDt(3, "Sub after")=1 // 実行ネームスペース
d Move
s ^nsDt(99, "end")=1 // 実行ネームスペース
q
Move
// ネームスペース切り替え処理
new $namespace
s $namespace = "USER"
s ^nsDt(4, "sub")=1 // USERネームスペース
q
}
ClassMethod Sub()
{
// ネームスペース切り替え処理
new $namespace
s $namespace = "USER"
s ^nsDt(2, "sub")=1 // USERネームスペース
}
上記を実行すると、各ネームスペースは下記グローバルが格納されます。
ラベル内や関数内での処理のみ、別のネームスペースに書き込まれている事が確認できます。
仮にスタック内でエラーが発生しても、元の処理に影響がないのが良いです。
znspace(zn)
ターミナルでネームスペースを切り替える際によく利用していると思います。
ネームスペース切り替えでは、一番メジャーなコマンドですよね。
この「znspace(zn)」コマンドは$namespaceと異なり、一度切り替えたらそのネームスペースを維持し続けます。
そのため、元のネームスペースに戻るときは、再度切り替え処理を実行する必要があります。
ClassMethod main()
{
s ^nsDt(1, "start")=1 // 実行ネームスペース
d ..Sub()
s ^nsDt(3, "Sub after")=1 // USERネームスペース
zn "sample"
d Move
s ^nsDt(99, "end")=1 // USERネームスペース
q
Move
// ネームスペース切り替え処理
zn "USER"
s ^nsDt(4, "sub")=1 // USERネームスペース
}
ClassMethod Sub()
{
// ネームスペース切り替え処理
zn "USER"
s ^nsDt(2, "sub")=1 // USERネームスペース
}
上記を実行すると、各ネームスペースは下記グローバルが格納されます。
znspace(zn)は、一度切り替えると元に戻らない為、全てネームスペース「USER」に書き込まれている事が確認できました。
下記コマンドも、znspaceと同様の動作を行います。
s $znspace = "USER"
d $zu(5,"USER")
使い分け
ドキュメントにも記載されていますが、一連の処理の流れでネームスペースを切り替えるのであれば、「new $namespace」が使い勝手が良いです。
何より、ネームスペースの切り替え漏れによる事故を防ぐ事ができるのが良いです。
ターミナルでの切り替えであれば、圧倒的にタイピング数が減る「zn」一択ですね。
%SYS.Namespace備忘録
冒頭で少しだけ触れた「%SYS.Namespace.cls」に関する、他の関数を備忘的に記載します。
詳細はドキュメントを確認していただけると助かります。
GetAllNSInfo
デフォルトのグローバル データベースとルーチン データベースに関する情報を返す。
→Get All NameSpace Infoの略ですかね
k info
d ##class(%SYS.Namespace).GetAllNSInfo("sample", .info)
zw info
// 下記が出力される
// info("GlobalDB","Directory")="d:\irisdb\sample-data\"
// info("GlobalDB","Mounted")=1
// info("GlobalDB","ReadOnly")=0
// info("GlobalDB","Resource")="%DB_%DEFAULT"
// info("GlobalDB","Status")=1
// info("GlobalDB","System")=""
// info("RoutineDB","Directory")="d:\irisdb\sample\"
// info("RoutineDB","Mounted")=1
// info("RoutineDB","ReadOnly")=0
// info("RoutineDB","Resource")="%DB_%DEFAULT"
// info("RoutineDB","Status")=1
// info("RoutineDB","System")=""
GetNSInfo
デフォルトのグローバル データベースに関する情報を返す。
k info
d ##class(%SYS.Namespace).GetNSInfo("sample", .info)
zw info
// 下記が出力される
// info("Directory")="d:\irisdb\sample-data\"
// info("Mounted")=1
// info("ReadOnly")=0
// info("Resource")="%DB_%DEFAULT"
// info("Status")=1
// info("System")=""
GetGlobalDest
指定したグローバルに対し、マッピングDBのディレクトリを返す。
s gblNm = "^nsDt"
w ##class(%SYS.Namespace).GetGlobalDest("sample","^nsDt")
// ^d:\irisdb\sample-data\ を返す
s gblNm = "^developer.data.Defrag4D"
w ##class(%SYS.Namespace).GetGlobalDest("sample","^nsDt")
// ^d:\irisdb\test64\ を返す
GetPackageDest
指定したパッケージに対し、マッピングDBのディレクトリを返す。
s pgNm = "HS"
w ##class(%SYS.Namespace).GetPackageDest("sample", pgNm)
// ^d:\iris\mgr\hslib\ を返す
GetRoutineDest
指定したルーチンに対し、マッピングDBのディレクトリを返す。
s rtnNm = "HSMOD.*"
w ##class(%SYS.Namespace).GetRoutineDest("sample", rtnNm)
// ^d:\iris\mgr\hslib\ を返す
おわりに
この記事では、ネームスペース切り替えについて、その基本手順や注意点、効率的な活用方法をお伝えしました。
業務の中でネームスペースの切り替えを行う機会は、そう多くはないかもしれません。
しかし、必要なときにスムーズに対応できるよう、ぜひ頭の片隅に留めておいていただければ幸いです。