精華區beta mud 關於我們 聯絡資訊
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]]; } 實裝上述程式碼後,測試結果如下... > 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)