2012-08-02 7 views
6

Ist es möglich, einen Wrapper um eine Funktion zu erstellen, die genau den gleichen Namen wie die ursprüngliche Funktion hat?Wie umschließt man eine bereits existierende Funktion mit einer neuen Funktion gleichen Namens?

unter Umständen Dies wäre sehr nützlich, wenn der Benutzer wünscht, einige zusätzliche Kontrollen auf Eingangsvariablen zu tun, bevor sie in Funktion auf den eingebauten geben werden How to interrupt MATLAB IDE when it hangs on displaying very large array?

+0

Ich bin damit einverstanden, die Antwort, die Sie auf der anderen Frage gestellt (http://stackoverflow.com/questions/11779511/how-to-interrupt-matlab-ide-when-it-hangs-on-displaying-very-large- Array) ist gut für diese Frage slayton, aber die allgemeine Frage hat eine bessere Antwort - siehe unten. – jmetz

Antwort

11

Eigentlich alternativ Slayton Antwort Sie nicht brauchen Verwenden Sie openvar. Wenn Sie eine Funktion mit demselben Namen wie eine Matlab-Funktion definieren, wird diese Funktion schattiert (also stattdessen aufgerufen).

Um dann zu vermeiden rekursiv aufrufen eigene Funktion, können Sie die ursprüngliche Funktion aus dem Wrapper mit builtin aufrufen.

z.B.

outputs = builtin(funcname, inputs..); 

Einfaches Beispiel, mit dem Namen rand.m und in dem Matlab-Pfad:

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

Hinweis, dass dies funktioniert nur für Funktionen, die von builtin zu finden sind. Für diejenigen, die das nicht tun, ist Slaytons Ansatz wahrscheinlich notwendig.

+0

aber es gibt so viele Funktionen, die nicht "eingebaut" sind und ich möchte sie alle verpacken! –

+0

@GuntherStruyf: warum möchten Sie alle von ihnen einwickeln ... besonders die nicht eingebauten? – jmetz

+0

Bei der Arbeit sind unsere Matlab-Installationen schreibgeschützt, daher ist es nicht möglich, die Dateien selbst zu ändern. Und es ist nicht bequem, immer meinen Spaß anstelle von Spaß zu benutzen. vor allem, wenn es darum geht, das Standardverhalten zu verbessern. Real-World-Anwendung: [Daniel Kesslers Problem] (http://stackoverflow.com/questions/11779511/how-to-interrupt-matlab-ide-when-it-hangs-on-displaying-yy-large-array) –

3

Ja, das ist möglich, aber es erfordert ein wenig Hacking. Es erfordert, dass Sie einige Funktionshandles kopieren.

Anhand des Beispiels in der Frage werde ich zeigen, wie Sie die Funktion openvar in eine benutzerdefinierte Funktion umwandeln, die die Größe der Eingabevariablen überprüft und dann den Benutzer jede offene Operation für zu große Variablen abbrechen kann.

Darüber hinaus sollte dies funktionieren, wenn der Benutzer im Arbeitsbereich der Matlab-IDE auf eine Variable doppelklickt.

Wir müssen drei Dinge tun.

  1. Erhalten Sie einen Griff zum Original openvar Funktion
  2. die Wrapper-Funktion definieren, die openvar
  3. Umleiten der ursprünglichen openvar Namen auf unserer neuen Funktion aufruft.

Beispiel Funktion

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 

Sobald diese Funktion dann müssen Sie definiert ist einfach ein Skript auszuführen, dass

  • alle Variablen openvar
  • laufen namens Löscht das openVarWrapper Skript zum Einrichten der Verbindung
  • zeigen Sie das Original,21 Tausend zu openVarWrapper

Beispiel Script:

clear openvar; 
openVarWrapper; 
openvar = @openVarWrapper; 

Schließlich, wenn Sie wollen, dass alles aufzuräumen können Sie einfach anrufen:

clear openvar; 
+0

Es sollte einfacher sein, die Handle zu der Shadowed-Funktion zu bekommen, nur aus dem Dateipfad, um genau zu sein. Ihre Lösung erfordert eine Initialisierung (jedes Mal, wenn Sie 'clear all 'verwenden). [Meine Lösung] (http://stackoverflow.com/a/11781650/1162609) erfordert cd auf den Pfad und zurück, aber das ist alles Hacker. Ich hoffe immer noch, dass jemand einen besseren Weg hat: p –

Verwandte Themen