2012-08-02 83 views
6

是否有可能爲與原始函數名稱完全相同的函數創建一個包裝?如何用同名的新函數包裝已有的函數

這將是在用戶想要做的輸入變量一些額外的檢查都通過,纔到內置的功能How to interrupt MATLAB IDE when it hangs on displaying very large array?

+0

我同意你在其他問題上發佈的答案(http://stackoverflow.com/questions/11779511/how-to-interrupt-matlab-ide-when-it-hangs-on-displaying-very-large-數組)對於slayton這個問題是很好的,但是一般問題有更好的答案 - 見下文。 – jmetz 2012-08-02 16:49:53

回答

11

其實備選地斯雷頓的回答,你不需要使用openvar。如果你定義一個和matlab函數同名的函數,它將會影響該函數(也就是被調用)。

爲了避免再遞歸調用自己的功能,您可以通過使用builtin從包裝內調用原始函數。

例如

outputs = builtin(funcname, inputs..); 

簡單的例子,一個名爲rand.m並在MATLAB路徑:

function out = main(varargin) 
disp('Test wrapping rand... calling rand now...'); 
out = builtin('rand', varargin{:}); 

注意,這僅適用於功能的作品由builtin發現。對於那些沒有,slayton的方法可能是必要的。

+0

但是有太多的函數沒有被「內置」,我想把它們全部包裝起來! – 2012-08-02 19:00:10

+0

@GuntherStruyf:你爲什麼要包裝所有這些......特別是非內置的? – jmetz 2012-08-02 19:12:39

+0

在工作中,我們的matlab安裝程序是隻讀的,因此無法更改文件本身。總是使用myfunins而不是樂趣。特別是當它改善默認行爲時。真實世界的應用程序:[丹尼爾凱斯勒的問題](http://stackoverflow.com/questions/11779511/how-to-interrupt-matlab-ide-when-it-hangs-on-displaying-very-large-array) – 2012-08-03 05:31:19

3

是的,這是可能的,但它需要一些黑客的情況下非常有用的。它需要你複製一些功能句柄。

使用問題中提供的示例,我將演示如何將函數openvar包裝在用戶定義的函數中,該函數檢查輸入變量的大小,然後允許用戶取消對變量太大的任何打開操作。

此外,這應該工作,當用戶雙擊在Matlab IDE的工作區面板的變量。

我們需要做三件事。

  1. 得到一個處理原始openvar功能
  2. 定義調用openvar
  3. 包裝函數重定向原來openvar名到我們的新功能。

示例功能

function openVarWrapper(x, vector) 

    maxVarSize = 10000; 
    %declare the global variable 
    persistent openVarHandle; 

    %if the variable is empty then make the link to the original openvar 
    if isempty(openVarHandle) 
     openVarHandle = @openvar; 
    end 

    %no variable name passed, call was to setup connection 
    if narargin==0 
     return; 
    end 


    %get a copy of the original variable to check its size 
    tmpVar = evalin('base', x);   

    %if the variable is big and the user doesn't click yes then return 
    if prod(size(tmpVar)) > maxVarSize 
     resp = questdlg(sprintf('Variable %s is very large, open anyway?', x)); 
     if ~strcmp(resp, 'Yes') 
      return; 
     end 
    end 

    if ischar(x) && ~isempty(openVarHandle); 
     openVarHandle(x); 
    end 
end 

一旦這個函數的定義,那麼你只需要執行一個腳本,

  • 清除名爲openvar
  • 任何變量運行openVarWrapper腳本來設置連接
  • 原點openVaropenVarWrapper

示例腳本:

clear openvar; 
openVarWrapper; 
openvar = @openVarWrapper; 

最後,當你想清理的一切行動,你可以簡單地調用:

clear openvar; 
+0

只需從文件路徑中獲取對陰影函數的句柄就應該更容易。你的解決方案需要一些初始化(每次你使用'clear all')。 [我的解決方案](http://stackoverflow.com/a/11781650/1162609)需要cd'ing到路徑和回來,但這都是hackery。我仍然希望有人想出一個更好的方法:p – 2012-08-02 18:58:02