2012-08-02 12 views
6

È possibile creare un wrapper attorno a una funzione che ha esattamente lo stesso nome della funzione originale?Come racchiudere una funzione già esistente con una nuova funzione con lo stesso nome

Questo sarebbe molto utile nel caso in cui l'utente vuole fare alcuni controlli aggiuntivi su variabili di ingresso prima di essere passati al costruito in funzione How to interrupt MATLAB IDE when it hangs on displaying very large array?

+0

Accetto la risposta che hai postato sull'altra domanda (http://stackoverflow.com/questions/11779511/how-to-interrupt-matlab-ide-when-it-hangs-on-displaying-very-large- array) è buono per quella domanda di slayton, ma la domanda generale ha una risposta migliore - vedi sotto. – jmetz

risposta

11

realtà alternativa per Slayton di risposta che non è necessario utilizzare openvar. Se si definisce una funzione con lo stesso nome di una funzione MATLAB, essa ombreggia quella funzione (ad esempio, si deve chiamare).

Per evitare di chiamare ricorsivamente la propria funzione, è possibile chiamare la funzione originale all'interno del wrapper utilizzando builtin.

ad es.

outputs = builtin(funcname, inputs..); 

semplice esempio, di nome rand.m e nel percorso di MATLAB:

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

Nota che questo funziona solo per le funzioni che si trovano da builtin. Per quelli che non lo sono, l'approccio di Slayton è probabilmente necessario.

+0

ma ci sono così tante funzioni che non sono "integrate" e voglio completarle tutte! –

+0

@GuntherStruyf: perché vorresti avvolgerli tutti ... in particolare quelli non di costruzione ?? – jmetz

+0

Al lavoro, le nostre installazioni MATLAB sono di sola lettura, quindi non è possibile modificare i file stessi. E non è conveniente usare sempre myfuninstead di divertimento. specialmente quando si tratta di migliorare il comportamento predefinito. Applicazione del mondo reale: [il problema di Daniel Kessler] (http://stackoverflow.com/questions/11779511/how-to-interrupt-matlab-ide-when-it-hangs-on-displaying-very-large-array) –

3

Sì questo è possibile ma richiede un po 'di hacking. Richiede che copi alcuni handle di funzione.

Utilizzando l'esempio fornito nella domanda, mostrerò come racchiudere la funzione openvar in una funzione definita dall'utente che controlla la dimensione della variabile di input e quindi consente all'utente di annullare qualsiasi operazione aperta per le variabili troppo grandi.

Inoltre, questo dovrebbe funzionare quando l'utente fa doppio clic su una variabile nel riquadro Area di lavoro di Matlab IDE.

Abbiamo bisogno di fare tre cose.

  1. ottenere un handle alla funzione originale openvar
  2. Definire la funzione wrapper che chiama openvar
  3. reindirizzare il openvar nome originale per la nostra nuova funzione.

Esempio Funzione

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 

Una volta che questa funzione è definita, allora avete semplicemente bisogno di eseguire uno script che

  • Azzera tutte le variabili denominate openvar
  • esegue lo script openVarWrapper per impostare la connessione
  • point l'originale openVar a openVarWrapper

Esempio Script:

clear openvar; 
openVarWrapper; 
openvar = @openVarWrapper; 

Infine, quando si desidera pulire tutto si può semplicemente chiamare:

clear openvar; 
+0

dovrebbe essere più semplice ottenere l'handle della funzione ombreggiata, solo dal percorso file per essere precisi. La tua soluzione richiede un'inizializzazione (ogni volta che usi 'clear all'). [La mia soluzione] (http://stackoverflow.com/a/11781650/1162609) richiede l'esecuzione di cd'ing sul percorso e ritorno, ma questo è tutto l'hackery. Spero ancora che qualcuno si presenti in un modo migliore: p –

Problemi correlati