2013-07-18 2 views
9

primo luogo, qui il modo in cui sto chiamando la funzione:Come selezionare una funzione .m specifica quando ne esistono due?

eval([functionName '(''stringArg'')']); % functionName = 'someStringForTheFunctionName' 

Ora, ho due functionName funzioni nel mio percorso, uno che prende la e un altro stringArg che prende qualcos'altro. Sto ricevendo alcuni errori perché in questo momento il primo che trova è la funzione che non prende lo stringArg. Considerando il modo in cui sto chiamando la funzione functionName, come è possibile chiamare la funzione corretta?

Edit:

ho provato la funzione which:

which -all someStringForTheFunctionName 

Il risultato:

C:\........\x\someStringForTheFunctionName 
C:\........\y\someStringForTheFunctionName % Shadowed 

La funzione ombra è quella che voglio chiamare.

+1

domanda correlata: [Eseguendo un file o chiamando una funzione il cui file è inserito in un'altra cartella con MATLAB?] (http://stackoverflow.com/questions/6153323/) –

+0

Accidenti a Eitan, trovi sempre risposte come minuti prima di me haha buona chiamata però! – Shaun314

risposta

7

I nomi di funzione devono essere univoci in MATLAB. Se non lo sono, quindi ci sono nomi duplicati, MATLAB usa il primo che trova sul tuo percorso di ricerca.

Detto questo, ci sono alcune opzioni aperte a voi.

Opzione 1. Utilizzare le directory @, inserendo ciascuna versione in una directory separata. Essenzialmente stai usando la capacità di MATLAB di applicare una funzione a classi specifiche. Quindi, si potrebbe impostare un paio di directory:

@char 
@double 

mettere la vostra copia dei myfun.m nelle rispettive directory. Ora, quando MATLAB vede un doppio input per myfun, indirizzerà la chiamata alla versione doppia. Quando MATLAB riceve l'input del char, va alla versione char.

ATTENZIONE. Non mettere queste directory @ esplicitamente sul tuo percorso di ricerca. Mettili ALL'INTERNO una directory che si trova sul tuo percorso di ricerca.

Un problema con questo schema è se si chiama la funzione con un input di precisione SINGLE, MATLAB avrà probabilmente un adattamento, quindi avresti bisogno di versioni separate per singolo, uint8, int8, int32, ecc. Non puoi semplicemente averne uno versione per tutti i tipi numerici.

Opzione 2. Avere solo una versione della funzione, che verifica il primo argomento per vedere se è numerica o char, quindi dirama per eseguire le attività in modo appropriato. Entrambi i pezzi di codice si troveranno più semplicemente in un file allora. Lo schema semplice avrà subfunzioni o funzioni annidate per fare il lavoro.

Opzione 3. Assegnare un nome alle funzioni in modo diverso. Ehi, non è la fine del mondo.

Opzione 4: come sottolinea Shaun, si può semplicemente cambiare la directory corrente. MATLAB cerca sempre prima nella tua directory corrente, quindi troverà la funzione in quella directory, se necessario. Un problema è che richiede tempo. Ogni volta che tocchi una directory, le cose rallentano, perché ora è necessario l'input del disco.

La parte peggiore della modifica delle directory riguarda l'utilizzo di MATLAB. È (IMHO) uno stile di programmazione scadente per forzare l'utente a trovarsi sempre in una directory specifica in base a quali input di codice desiderano eseguire. Meglio è uno schema guidato dai dati. Se stai leggendo o scrivendo i dati, allora sii in quella directory.Usa il percorso di ricerca MATLAB per classificare tutte le tue funzioni, poiché le funzioni tendono a non cambiare molto. Questo è un modo di operare molto più pulito rispetto al richiedere all'utente di migrare a directory specifiche in base a come chiameranno una determinata funzione.

Personalmente, tenderei a suggerire l'opzione 2 come la migliore. È pulito. Ha solo UNA funzione principale con cui devi lavorare. Se si desidera mantenere il distretto delle funzioni, inserirle come funzioni nidificate o secondarie separate all'interno del corpo della funzione principale. All'interno, naturalmente, avranno nomi distinti, basati su come sono guidati.

+0

In alternativa, basta cambiare la directory prima di chiamarla e quindi cambiarla di nuovo dopo essere stata chiamata. Non è possibile creare file aggiuntivi, modificare nomi o mettere insieme funzioni, in totale sono sufficienti due linee di codice base. – Shaun314

0

EDIT: Vecchio risposta non va più bene

il comando di marcia non funziona perché la sua funzione, non uno script.

Invece, il tuo migliore approccio sarebbe onestamente solo capire quale delle funzioni devono essere eseguite, ottenere la directory corrente, cambiarla in quella in cui si trova la funzione, eseguirla e quindi tornare alla directory di avvio .

Questo approccio, sebbene non perfetto, sembra MOLTO più facile da codificare, da leggere e meno incline alla rottura. E non richiede la modifica dei nomi o la creazione di file o handle di funzioni aggiuntivi.

+0

Sembra che sia solo per 'Script ', non funzioni. –

+0

Ok, sì, vedo che deve lavorare con le variabili nello spazio di lavoro di MATLAB, hmm, credo che potresti creare uno script di wrapper, ma questo annullerebbe praticamente l'intero scopo di questa domanda .. – Shaun314

+0

Sì. Esegui si applica solo agli script. E gli script non possono accettare input variabili. –

2

OK, quindi una risposta disordinata, ma dovrebbe farlo. La mia funzione di test era 'echo'

funcstr='echo'; % string representation of function 

Fs=which('-all',funcstr); 
for v=1:length(Fs) 
    if (strcmp(Fs{v}(end-1:end),'.m')) % Don''t move built-ins, they will be shadowed anyway 
     movefile(Fs{v},[Fs{v} '_BK']); 
    end 
end 
for v=1:length(Fs) 
    if (strcmp(Fs{v}(end-1:end),'.m')) 
     movefile([Fs{v} '_BK'],Fs{v}); 
    end 
    try 
     eval([funcstr '(''stringArg'')']); 
     break; 
    catch 
     if (strcmp(Fs{v}(end-1:end),'.m')) 
      movefile(Fs{v},[Fs{v} '_BK']); 
     end 
    end 
end 
for w=1:v 
    if (strcmp(Fs{v}(end-1:end),'.m')) 
     movefile([Fs{v} '_BK'],Fs{v}); 
    end 
end 
+0

Quindi ho due scelte, # 1 cambia directory e tornare alla directory iniziale o # 2 spostare il file nella directory corrente (cambiarne il nome) e spostarlo indietro (cambiare il suo nome indietro)! –

1

È inoltre possibile creare un handle di funzione per la funzione ombreggiata. Il problema è che la prima funzione è più alta nel percorso MATLAB, ma è possibile aggirarla modificando (temporaneamente) la directory corrente.

Anche se non è bello cambiare la directory corrente (in realtà preferirei non cambiarla mai durante l'esecuzione del codice), risolverà il problema abbastanza facilmente; soprattutto se lo si utilizza nella parte di configurazione della funzione con un manico funzione di persistente:

function outputpars = myMainExecFunction(inputpars) 
    % configuration 
    persistent shadowfun; 
    if isempty(shadowfun) 
     funpath1 = 'C:\........\x\fun'; 
     funpath2 = 'C:\........\y\fun'; % Shadowed 

     curcd = cd; 
     cd(funpath2); 
     shadowfun = @fun; 
     cd(curcd); % and go back to the original cd 
    end 

    outputpars{1} = shadowfun(inputpars); % will use the shadowed function 
    oupputpars{2} = fun(inputparts); % will use the function highest on the matlab path 
end 

Questo problema è stato discusso anche here come una possibile soluzione per this problem.

credo che in realtà è l'unico modo per sovraccaricare una funzione built-in al di fuori della directory dei sorgenti della funzione di sovraccarico (ad es. Si desidera eseguire il proprio sum.m in una directory diversa da quella in cui si trova il vostro sum.m.)