下面的函數會給你你想要的 - 子類名稱,它是在調用(繼承的)靜態超類方法時使用的。只是把它的父類方法裏像你將任何正常功能:
className = getStaticCallingClassName();
它所確實手柄:
- 無論何時編程方式(通過正在運行的腳本/功能,即在調用方法的情況下),以及從命令窗口調用的時間。
- 任意嵌套的軟件包名稱(即位於以
+
爲前綴的目錄中的類)。
它所不手柄:
- 不工作,如果靜態方法被稱爲在非靜態的情況下,即對對象實例。但是你不應該使用這樣的語法。如果我們可以遞歸地使用
evalin
和'caller'
工作區,但這種方式不可行。
這個想法背後的簡單解釋:由dbstack
生成的堆棧跟蹤中的第二項對應於超類,我們可以使用它來提取靜態方法名稱。接下來的步驟取決於:
- 如果方法調用編程,第三堆棧條目將指向我們的父腳本/功能,我們需要閱讀,例如一條線使用
dbtype
。剩下要做的就是根據方法名稱使用regexp
提取子類名稱。
- 如果從命令窗口調用該方法,我們查詢最後一個命令並將其用作正則表達式的輸入。
請注意,即使堆棧有3個或更多條目,也不表示該方法是以編程方式調用的。例如,如果我們停在某處的斷點處並從命令窗口調用該方法,則堆棧跟蹤將很長,但基於來自第三個堆棧跟蹤條目的行的regexp
不會給我們答案。在這種情況下,我們回到命令窗口的方法。
警告:它嚴重依賴未記錄的功能,並可能在任何功能版本中崩潰。在Matlab 2015b上測試,但也應該適用於大多數以前的版本。有人可能會說它很髒,但它運行得很好,而且它是我意識到實現這種行爲的唯一方法。
function [className, fullPath] = getStaticCallingClassName()
ST = dbstack('-completenames');
% First one is getStaticCallingClassName, second one is the superclass
methodName = char(regexp(ST(2).name, '[^\.]([^.]*)$', 'match'));
% matches string (combination of alphanumeric/underscore/dot characters) preceeding the given method call.
pattern = sprintf('[\\w.-]*(?=.%s)', methodName);
% If the parent called static method programmatically, we should be able to find it via the next (third) stack trace
if length(ST) > 2
command = evalc('dbtype(ST(3).file, num2str(ST(3).line))');
className = char(regexp(command, pattern, 'match'));
else % was likely called from command window. Long stack trace means that we're simply waiting in a breakpoint somewhere
className = []; % go straight to command window approach
end
if isempty(className) % means that static method was called directly from command window
javaHistory = com.mathworks.mlservices.MLCommandHistoryServices.getSessionHistory();
command = char(javaHistory(end));
className = char(regexp(command, pattern, 'match'));
end
fullPath = which(className);
end
你能展示你的一個子類是什麼樣的嗎?我無法按照您設置的方式創建與您的超類一起工作的子類。 – Suever
您可以通過檢查堆棧來獲取它。但我認爲最好將實例或類名傳遞給此方法。 – Navan
MATLAB中沒有遲到的靜態綁定。 dbstack可能是你最好的選擇。 – siliconwafer