2015-08-29 10 views
9

Matlab consente di sovrascrivere funzioni incorporate senza preavviso.Come posso proteggere da scrittura il linguaggio Matlab?

Ad esempio, ho sovrascritto la funzione max() con una variabile, ma Matlab non mi avvisa di questo. Un errore viene generato solo più tardi quando viene chiamata la funzione, e non aiuta a vedere il vero problema: messaggio

min  = 0; 
max  = 10; 
x  = linspace(min,max,20); 
y  = exp(x); 
disp(['the value is: ', num2str(max(y))]) 

Errore:

Subscript indices must either be real positive integers or logicals. 

C'è un modo per scrivere proteggere tutti del linguaggio Matlab all'avvio o in un file di impostazioni per impedirlo?

+3

Interessante domanda. Cosa vuoi se digiti 'max = 3'? Un errore, niente, un avvertimento ...? Puoi sempre assicurarti di eseguire la funzione incorporata usando 'builtin', come questo' x = builtin ('max', [- 4, 3]) ', ma questo è ovviamente molto complicato. _Assicurati di non [overload 'builtin'] (http://stackoverflow.com/a/18360748/2338750) !! _ –

+0

Beh ... un errore/avvertimento quando sovrascrivo sarebbe bello. Così un avviso nell'editor interattivo. Piacere di conoscere la funzionalità 'builtin', ma probabilmente cambierei semplicemente il nome della mia variabile. – ConfusinglyCuriousTheThird

+1

Immagino che questo non sia possibile. Forse solo quando sovraccarichi ** ogni ** singola classe fondamentale in Matlab http://de.mathworks.com/help/matlab/matlab_prog/fundamental-matlab-classes.html Ma io non lo consiglio. Può rendere Matlab inutile quando stai sbagliando. Ma puoi sempre verificare con '>> exist possible_var_name' se già esiste. '>> which something_that_exist' ti dice da dove viene o cosa è. – Markus

risposta

1

partire dal 9/2015, Non ho trovato un modo per facilmente scrivere le funzioni/lingua native matlab, come impostazione/flag/etc at tartup.

Se si è preoccupati per una particolare funzione, ci sono vari modi per vedere se sono ombreggiati, compresa la risposta di Luis Mendo: which('name_of_function', '-all').

Se un metodo viene trovato in futuro, accetterò volentieri tale risposta!

4

Non conosco un modo per fare ciò che vuoi. Ma c'è un modo per verificare se una funzione specifica è stata ombreggiata, tramite una variabile o un'altra funzione, utilizzando which: vale a dire, analizzare l'output di which(fname, '-all'), dove fname è una stringa contenente il nome della funzione.

Prendere la funzione max come esempio: confronta (senza ombra)

>> clear all 
>> fname = 'max'; 
>> which(fname, '-all') 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@logical\max) % logical method 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@char\max)  % char method 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@double\max) % double method 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint8\max) % uint8 method 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint16\max) % uint16 method 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint32\max) % uint32 method 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint64\max) % uint64 method 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int8\max)  % int8 method 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int16\max) % int16 method 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int32\max) % int32 method 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int64\max) % int64 method 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@single\max) % single method 
C:\Program Files\MATLAB\R2010b\toolbox\matlab\timeseries\@timeseries\max.m  % timeseries method 
C:\Program Files\MATLAB\R2010b\toolbox\distcomp\parallel\@codistributed\max.m % codistributed method 
C:\Program Files\MATLAB\R2010b\toolbox\shared\statslib\@ordinal\max.m   % ordinal method 

con (shadowing)

>> fname = 'max'; 
>> max = 10; 
>> which(fname, '-all') 
max is a variable. 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@logical\max) % Shadowed logical method 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@char\max)  % Shadowed char method 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@double\max) % Shadowed double method 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint8\max) % Shadowed uint8 method 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint16\max) % Shadowed uint16 method 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint32\max) % Shadowed uint32 method 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint64\max) % Shadowed uint64 method 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int8\max)  % Shadowed int8 method 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int16\max) % Shadowed int16 method 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int32\max) % Shadowed int32 method 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int64\max) % Shadowed int64 method 
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@single\max) % Shadowed single method 
C:\Program Files\MATLAB\R2010b\toolbox\matlab\timeseries\@timeseries\max.m  % Shadowed timeseries method 
C:\Program Files\MATLAB\R2010b\toolbox\distcomp\parallel\@codistributed\max.m % Shadowed codistributed method 
C:\Program Files\MATLAB\R2010b\toolbox\shared\statslib\@ordinal\max.m   % Shadowed ordinal method 

Nel secondo caso, which(fname, '-all') si dice che max è una variabile che è shadowing diversi metodi.

Così, per verificare se è in atto shadowing,

  1. assegnare l'uscita di which(fname, '-all') ad una variabile.

    In linea di principio ciò può essere effettuato come s = which(fname, '-all');. Sfortunatamente, tuttavia, questo produce un output diverso; in particolare, la parte % ... nelle linee di cui sopra (che indica se v'è shadowing) viene rimosso:

    >> fname = 'max'; 
    >> s = which(fname, '-all') 
    s = 
        'variable' 
        'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@logical\max)' 
        'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@char\max)' 
        'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@double\max)' 
        'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint8\max)' 
        'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint16\max)' 
        'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint32\max)' 
        'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint64\max)' 
        'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int8\max)' 
        'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int16\max)' 
        'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int32\max)' 
        'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int64\max)' 
        'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@single\max)' 
        'C:\Program Files\MATLAB\R2010b\toolbox\matlab\timeseries\@timeseries\max.m' 
        'C:\Program Files\MATLAB\R2010b\toolbox\distcomp\parallel\@codistributed\max.m' 
        'C:\Program Files\MATLAB\R2010b\toolbox\shared\statslib\@ordinal\max.m' 
    

    così abbiamo bisogno di ricorrere a evalc per ottenere il risultato pieno: s = evalc('which(fname, ''-all'')');. Il risultato s è una stringa lunga che contiene tutte le linee (comprese le parti % ...) separati da caratteri di avanzamento riga:

    >> fname = 'max'; 
    >> s = evalc('which(fname, ''-all'')') 
    s = 
    max is a variable. 
    built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@logical\max) % Shadowed logical method 
    built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@char\max)  % Shadowed char method 
    built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@double\max) % Shadowed double method 
    built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint8\max) % Shadowed uint8 method 
    built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint16\max) % Shadowed uint16 method 
    built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint32\max) % Shadowed uint32 method 
    built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint64\max) % Shadowed uint64 method 
    built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int8\max)  % Shadowed int8 method 
    built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int16\max) % Shadowed int16 method 
    built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int32\max) % Shadowed int32 method 
    built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int64\max) % Shadowed int64 method 
    built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@single\max) % Shadowed single method 
    C:\Program Files\MATLAB\R2010b\toolbox\matlab\timeseries\@timeseries\max.m  % Shadowed timeseries method 
    C:\Program Files\MATLAB\R2010b\toolbox\distcomp\parallel\@codistributed\max.m % Shadowed codistributed method 
    C:\Program Files\MATLAB\R2010b\toolbox\shared\statslib\@ordinal\max.m   % Shadowed ordinal method 
    
  2. analizzare la stringa s ottenuto nella fase 1 per vedere se contiene '% Shadowed'. Questo è facilmente fatto con strfind: vale a dire, strfind(s, '% Shadowed') sarà non vuoto se c'è ombra.

In conclusione:

Mettere tutto insieme,

isShadowed = ~isempty(strfind(evalc('which(fname, ''-all'')'), '% Shadowed')); 

rendimenti true se la funzione con nome contenuto in variabile fname è ombreggiato e false altrimenti.

Esempio con una variabile:

>> clear all 
>> fname = 'max'; 
>> max = 10; 
>> isShadowed = ~isempty(strfind(evalc('which(fname, ''-all'')'), '% Shadowed')) 
isShadowed = 
    1 
>> clear max 
>> isShadowed = ~isempty(strfind(evalc('which(fname, ''-all'')'), '% Shadowed')) 
isShadowed = 
    0 

Esempio di una funzione denominata:

Creare una funzione nel file di std.m e inserirlo nel tuo percorso. Ciò ombreggia la funzione std di Matlab.

>> fname = 'std'; 
>> isShadowed = ~isempty(strfind(evalc('which(fname, ''-all'')'), '% Shadowed')) 
isShadowed = 
    1 

cancellare il file di funzione (o rimuovere la relativa cartella dal percorso):

>> fname = 'std'; 
>> isShadowed = ~isempty(strfind(evalc('which(fname, ''-all'')'), '% Shadowed')) 
isShadowed = 
    0 

Esempio con una funzione anonima:

>> std = @(x) x+1; 
>> fname = 'std'; 
>> isShadowed = ~isempty(strfind(evalc('which(fname, ''-all'')'), '% Shadowed')) 
isShadowed = 
    1 
>> clear std 
>> isShadowed = ~isempty(strfind(evalc('which(fname, ''-all'')'), '% Shadowed')) 
isShadowed = 
    0 
+0

Grazie Luis. Questa è una buona informazione, ma non è esattamente quello che sto cercando: /. Speravo che ci fosse una soluzione elegante, diciamo un flag "-nowrite" o una preferenza che potrei cambiare che potrebbe modificare il comportamento di matlab. Questo è utile una volta che una funzione è già stata sovrascritta. – ConfusinglyCuriousTheThird

+0

Sì, lo so.Quello che vuoi sarebbe interessante da raggiungere –