2011-09-15 23 views
1

我正在開發的項目有很多內置的遙測和調試機制,必須在發佈版本中提供,但絕不能在系統的大部分部分中使用。我想建立一個宏,在這樣的方法的頂部被調用,如果方法沒有被一個非常有限的模塊組中的一個調用,將會拋出一個異常。Erlang:有沒有比堆棧跟蹤中的正則表達式更好的方式來判斷堆棧中是否有東西?

例如,我有我可以用它來從控制檯操縱系統狀態的調試模塊,我有一個網絡工具,允許管理員檢查和更改系統。一些爲其使用而設計的方法(但是在整個系統中以模塊實現)對於偶爾使用而言是很好的,但是如果有人在將它們稱爲正常操作的一部分的過程中犯了錯誤,那麼這些方法會很糟糕。

編輯:我已經試過清單:keysearch建議,下,它可以用於任何模塊,我可以明確的名字,這可能是我曾經打算管理最好的。我有像web_foo,web_bar,web_foo_other,web_yippie_ki_yea_mf等模塊,以配合我回歸正則表達式。

我可以做類似以下的事情。 (我沒有編譯這個已經。我希望你給任何答案會阻止我曾經把這個投入生產。=]

try 
    %gotta do this to get the stacktrace: 
    throw(a) 
catch 
    _ -> 
    Stack = erlang:get_stacktrace(), 
    {_, RegExp} = re:compile("webmanager", [multiline]), 
    case Match = re:run(Stack, RegExp) of 
     nomatch -> 
     throw(im_sorry_dave__im_afraid_i_cant_do_that); 
     {match, _} -> 
     ok 
    end 
end 
+0

從我的小Erlang經驗來看,它看起來不像Erlang。我認爲最好不要使用try-catch。 – ipinak

回答

3

由於堆棧是代表方法調用元組的列表,您可以使用lists:keysearch(webmanager, 1, Stack)來檢查模塊是否在堆棧跟蹤中。

1

從你的描述我不明白爲什麼不來隔離不同的立面模塊或過程的背後操作的支持功能和調試的。這些進程代碼可以根據它們的屬性限制調用者,例如註冊名稱(全局,本地,gproc)或節點名稱。

-module(adm_facade). 
-export([register_admin_mode_proc/0, 
     unregister_admin_mode_proc/0, 
     adm1/1 
     ]). 

register_admin_mode_proc() -> 
    register(admin_mode_proc, self()). 

unregister_admin_mode_proc() -> 
    unregister(admin_mode_proc). 

adm(X) -> 
    check_adm(), 
    some_other_module:adm(X). 

check_adm() -> 
    Caller = self(), 
    case erlang:whereis(admin_mode_proc) of 
     Caller -> ok; 
     _ -> erlang:error({access_denied, Caller}) 
    end. 

當然這將管理功能限制爲單個調用者,但您可以使用gproc或您自己的註冊商。

+0

有問題的方法需要在包含他們檢查的數據的特定進程上執行,所以我無法根據進程ID限制調用者列表。我也考慮建立一個消息系統來支持這些特定的調用,但通信框架(非常複雜 - 我沒有寫這個東西)已經失去控制,我不需要再添加一個。 – Sniggerfardimungus