Definitivamente si tratta di un errore nel parser; Un bug perché non ha generato un errore per cominciare, e invece ti ha permesso di scrivere: obj.method.prop
in primo luogo!
Il fatto che MATLAB si sia arrestato in alcune varianti di questa sintassi è un bug grave e dovrebbe essere sicuramente reported in MathWorks.
Ora la regola generale in MATLAB è che non si dovrebbe "indicizzare in un risultato" direttamente. Invece, è necessario prima salvare il risultato in una variabile e quindi indicizzare la variabile.
Questo fatto è chiaro se si utilizza il modulo func(obj)
piuttosto che obj.func()
per richiamare i metodi dei membri per gli oggetti (dot-notation vs. function notation):
>> A = MyClass;
>> A.procData.data % or A.procData().data
ans =
[]
>> procData(A).data
Undefined variable "procData" or class "procData".
Invece, come avrete notato, è necessario utilizzare:
>> B = procData(A): % or: B = A.pocData;
>> [B.data]
FWIW, questo è anche ciò che accade quando si lavora con strutture semplici e funzioni regolari (al contrario di oggetti OOP e membri funzioni), poiché non è possibile indicizzare comunque il risultato di una chiamata di funzione. Esempio:
% a function that works on structure scalar/arrays
function s = procStruct(s)
if numel(s) > 1
for i=1:numel(s)
s(i) = procStruct(s(i));
end
else
s.data = abs(s.data);
end
end
Poi tutte le seguenti chiamate getteranno errori (come dovrebbero):
% 1x2 struct array
>> s = struct('data',{1 -2});
>> procStruct(s).data
Undefined variable "procStruct" or class "procStruct".
>> procStruct(s([1 2])).data
Undefined variable "procStruct" or class "procStruct".
>> feval('procStruct',s).data
Undefined variable "feval" or class "feval".
>> [email protected]; f(s([1 2])).data
Improper index matrix reference.
Si potrebbe chiedere se stessi perché hanno deciso di non permettere tale sintassi. Bene, si scopre che esiste una buona ragione per cui MATLAB non consente l'indicizzazione in una chiamata di funzione (senza dover introdurre una variabile temporanea), che si tratti dell'indicizzazione dei punti o dell'indicizzazione degli indici.
Prendere la seguente funzione per esempio:
function x = f(n)
if nargin == 0, n=3; end
x = magic(n);
end
Se abbiamo permesso l'indicizzazione in una chiamata di funzione, allora ci sarebbe un'ambiguità nel modo di interpretare la seguente chiamata f(4)
:
- dovrebbe essere interpretato come:
f()(4)
(ovvero la funzione di chiamata senza argomenti, quindi indicizzare nella matrice risultante utilizzando l'indicizzazione lineare per ottenere il quarto elemento)
- o dovrebbe esso nterpreted come:
f(4)
(chiamare la funzione con un argomento essendo n = 4, e riportare la matrice magic(4)
)
Questa confusione è causata da diversi fattori nella sintassi MATLAB:
permette chiamando funziona senza argomenti semplicemente con il loro nome, senza richiedere le parentesi. Se è presente una funzione f.m
, è possibile chiamarla come f
o f()
. Questo rende più difficile l'analisi del codice M, poiché non è chiaro se i token siano variabili o funzioni.
parentesi vengono utilizzate sia per l'indicizzazione della matrice che per le chiamate di funzione. Quindi se un token x
rappresenta una variabile, usiamo la sintassi x(1,2)
come indicizzazione nella matrice. Allo stesso tempo se x
è il nome di una funzione, quindi x(1,2)
viene utilizzato per chiamare la funzione con due argomenti.
Un altro punto di confusione è costituito da elenchi separati da virgole e funzioni che restituiscono più output. Esempio:
>> [mx,idx] = max(magic(3))
mx =
8 9 7
idx =
1 3 2
>> [mx,idx] = max(magic(3))(4) % now what?
dovessimo tornare al 4 ° elemento di ciascun variabili di uscita da MAX, o 4 ° elemento da solo il primo parametro di output insieme alla seconda uscita pieno? Che dire quando la funzione restituisce uscite di diverse dimensioni?
Tutto ciò vale ancora agli altri tipi di indicizzazione: f()(3)
/f(3)
, f().x
/f.x
, f(){3}
/f{3}
.
Per questo motivo, MathWorks ha deciso di evitare tutta la confusione di cui sopra e semplicemente di non consentire l'indicizzazione diretta nei risultati. Sfortunatamente hanno limitato la sintassi nel processo. Ad esempio, Octave non ha restrizioni di questo tipo (puoi scrivere magic(4)(1,2)
), ma il nuovo sistema OOP è ancora in fase di sviluppo, quindi non so come Octave si occupi di questi casi.
Per chi fosse interessato, questo mi ricorda un altro similar bug per quanto riguarda i pacchetti e classi e direttamente l'indicizzazione per ottenere una proprietà. I risultati erano diversi se lo si chiamava dal prompt dei comandi, da uno script o da una funzione di file M ...
Non riesco a riprodurre questo; funziona bene qui ... Quale versione di MATLAB stai usando? –
sto usando 2012a – dylan2106
2013a lo stesso "problema". Ma questo funziona '[A ([1 2]). Dati]' – Marcin