> call me;query;"name"
玩家(laechan /std/user)-> query( "name" ) =
"laechan"
> call me;query;"skill/barefist"
玩家(laechan /std/user)-> query( "skill/barefist"
) = 9900
這兩個值以傳統的讀取方式都能正確讀取。
然後我在 env 設了一個參數值 test_data
test_data :([ "test1" : ([ "test2" : ([ "test3" : 4 ]) ]) ])
然後做底下的動作..
> call here;query;"test_data/test1"
房間(/u/l/laechan/skycastle/room/street/supply1)-> query(
"test_data/test1" ) = ([ "test2" : ([ "test3" : 4 ]) ])
> call here;query;"test_data/test1/test2"
房間(/u/l/laechan/skycastle/room/street/supply1)-> query(
"test_data/test1/test2" ) = ([ "test3" : 4 ])
> call here;query;"test_data/test1/test2/test3"
房間(/u/l/laechan/skycastle/room/street/supply1)-> query(
"test_data/test1/test2/test3" ) = 4
傳統上,遇到資料層度較高的 map data,一般都不會將其以 ob->set
的方式來儲存,而是會在物件上宣告 mapping data 來處理,它的優點
是資料獨立於 ob_data 之外,具隱藏性(除非建立方式存取不然看不到
資料),缺點是需建立存取方法,無法以既有的 set/add/delete/query
等方式來操作。
這時若將這些函數改成支援遞迴,就可順利讀取深層資料,同樣的修改
可套用在 _set、_add、_delete 等由 /adm/simul_efun/prop_login.c
宣告的函數上。
一點心得,跟大家分享。這東西其實可有可無,因為通常資料層度三就
已經夠高了,而三轉二有變通做法,例如聖殿有 effect 設定..
set("effect/stat-str",10);
上面的 - 即是變通做法,若照一般結構應是 effect/stat/str,也就
是 data["effect"]["stat"]["str"] → data["effect"]["stat-str"]
,此即三轉二的簡易做法(以 - 做一種識別)。
遞迴改法的好處,是可用 _query 這個 simul_efun 來對 mapping 資料
做深層呼叫。
Laechan
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 210.61.157.53
※ 編輯: laechan 來自: 210.61.157.53 (02/26 11:36)
lpmud 的 _query 函數大概是這麼寫的...
mixed _query( mapping map, string label )
{
mapping v;
string *parts;
parts=explode( label, "/" );
v=map[parts[0]];
if( sizeof( parts )==1)
return v;
if( undefinedp(v) || !mapp(v) ) return 0;
return v[parts[1]];
}
這意思是說,如果 label = "exits/north",那麼它就回傳
map["exits"]["north"] 的值。
那麼,假設今天 map 是一個學校的資料,其結構如下..
map=([
"一年五班":([
"王小明":([
"英文":100,
"數學":100,
]),
]),
.
.
]);
那麼有沒有可能實現 query("一年五班/王小明/英文") 的
語法呢?_query 函數可以這樣改...
mixed _query( mapping map, string label )
{
int n,m;
mapping v;
string *parts;
parts=explode( label, "/" );
v=map[parts[0]];
n=sizeof( parts );
m=strlen(parts[0]);
if( n==1)
return v;
// 以上都不變只是令
// int n = sizeof(parts);
// int m=strlen(parts[0]);
// 底下便是多出來的兩行
else if(n>2)
return _query(map[parts[0]],label[m+1..strlen(label)-1]);
if( undefinedp(v) || !mapp(v) ) return 0;
return v[parts[1]];
}
實裝上述程式碼後,測試結果如下...