2016-01-23 18 views
17

SETUP Win7 64b, R2015b, 16 GB di RAM, CPU i7-2700MATLAB: tavolo prevalente() metodi

Il table() è un fundamental Matlab class che è anche sigillato, quindi non posso sottoclasse esso.

voglio correzione alcuni metodi di questa classe e aggiungere nuove quelli. Ad esempio, table.disp() è fondamentalmente rotto, ad es. prova NON disp(table(rand(1e7,1))), o dimentica il ; nella finestra di comando. La variabile richiede solo 76 MB di RAM, ma il display non ha buffer e bloccherà il tuo sistema!

  1. Posso ignorare metodi come table.disp() senza scrivere in matlabroot\toolbox\matlab\datatypes\@table?
  2. Posso estendere la classe tabella con un nuovo metodo in C:\MATLAB\@table\ismatrixlike.m? Perché ottengo

    ismatrixlike(table) 
    Undefined function 'ismatrixlike' for input arguments of type 'table'. 
    

    Ovviamente, ho fatto

    addpath C:\MATLAB\ 
    rehash toolboxcache 
    

    Ho anche provato clear all.

    Il percorso ha precedenza (alfabetica) su matlabroot, ma manca una definizione di classe table.m. Se aggiungo la definizione di classe nativa a C:\MATLAB\@table, allora posso eseguire il mio nuovo metodo (dopo un clear all). Tuttavia:

    >> methods(table) 
    
    Methods for class table: 
    
    classVarNames ismatrixlike table   varfun   
    convertColumn renameVarNames unstack  
    

    elenca solo i metodi nella nuova cartella \@table, anche se (alcuni dei) i vecchi metodi funzionano ancora, per esempio

    size(table) 
    

    Questo risolve in parte il problema, dal momento che ora, la cartella nativo \@table\private non è più, e quindi molti metodi nativi sono rotti accessibili!

Perché sto facendo questo? Perché non voglio aspettare altri 2 anni prima che sia stato corretto il table(). Ho già perso interi giorni perché ho semplicemente dimenticato un ; nella finestra di comando e non riesco a forzare un riavvio sul mio PC se sta eseguendo simulazioni multiday, ma devo aspettare che il disk-swap finisca :(.

APPENDICE Maggiori contesto su disp(table(rand(1e7,1))) Questo è quello che succede quando ho colpito (e per fortuna io sono abbastanza veloce per CTRL-C fuori di esso):.

enter image description here

il colpevole è la linea 172 di table.disp() che converte l'array numerico in una stringa di celle (anche con il padding!):

[cells, err, isLeft] = sprintfc(f, x, b); 
+1

Ottenere Matlab per fare tutto ciò che * non * è già in una cassetta degli attrezzi ... dolore garantito. Abbandona ogni speranza, voi che entrate qui! – hoosierEE

+0

Si noti che 'istable' non è un metodo della classe della tabella, ma piuttosto una sua funzione che chiama' isa (t, 'table') '. – Suever

+0

@Siever grazie per aver notato che. Lo cambierò in 'table.size()' – Oleg

risposta

1

le seguenti opere per me:

  1. Definire una modificato funzione di disp, dicono disp_modified.m, come segue, e metterlo nel vostro percorso:

    function disp_modified(t) 
    if istable(t) 
        %// Do whatever you want to display tables 
        builtin('disp', '''disp'' function intercepted!') 
    else 
        %// For non-tables, call `disp` normally 
        builtin('disp', t) 
    end 
    
  2. Definire disp come function handle alla funzione modificata (è possibile farlo in startup.m per impostarlo sempre per impostazione predefinita):

    disp = @disp_modified; 
    

Dopo questo, nella finestra di comando ottengo

>> disp(1:5) 
    1  2  3  4  5 
>> disp({1 2 3 'bb'}) 
    [1] [2] [3] 'bb' 
>> disp(table(rand(1e3,1))) 
'disp' function intercepted! 
+2

Ciò richiede di chiamare esplicitamente 'disp'. Credo che voglia sovraccaricare la chiamata interna di 'table' a disp che sempre (a prescindere dalle funzioni locali) usa il' disp' incorporato. Questo è almeno ciò che sarebbe necessario per impedire ciò che accade quando ometti un punto e virgola. – Suever

+0

Questa soluzione è abbastanza hacky. Non intercetta implicit 'disp()' mancando ';' e potenzialmente incoraggia una pratica pericolosa. Inoltre, non è scalabile e temporaneo. Cosa dovrei fare dopo un 'clear'? Ridefinendo tutte le variabili disp-like per ogni metodo? – Oleg

+0

Invece di chiamare la funzione 'disp_modified' si può chiamare' disp', quindi non è influenzato da clear. – Daniel

2

Dopo aver sperimentato diverse alternative, ho adottato la soluzione che intereferes poco con nativo @table implementazione di Matlab e è facilmente rimosso se le cose vanno male.

La soluzione:

  • copia l'intera cartella @table, vale a dire fullfile(matlabroot,'toolbox','matlab','datatypes','@table'), in un destinazione che viene alfabeticamente prima cartella @table (vedi Class Precedence and MATLAB Path) e su cui avete permessi di scrittura.

    Ho scelto il destinazione essere fullfile(matlabroot,'toolbox','local','myfiles') dal momento che non c'è bisogno di perdere tempo con OS cross-compatibilità, cioè matlabroot prende cura di questo per me.

  • pasta nella destinazione cartella intera @table con i nuovi, sovraccarichi e imperativi metodi.

  • aggiungere il destinazione al percorso MATLAB.

Effetti, pro e contro:

  • il nativo @table classe/metodi sono ora in ombra, per esempio provare which table -all. Tuttavia, questo effetto è abbastanza chiaro, facilmente rilevabile e facilmente rimovibile (eliminare la destina- zione e rimuovere il percorso);
  • Nessun conflitto strano tra il numero nativo @table (ora ombreggiato) e il nuovo @table;
  • Tutti i metodi, nuovi e vecchi, sono visibili, prova methods(table);
  • I metodi tabella privata sono accessibili ...
  • ... ma si è costretti a usarli.
  • L'esposizione dei nuovi metodi (implementati dall'utente) a quelli privati ​​richiede più manutenzione e gestione diretta dei conflitti di versione nelle implementazioni della tabella.
  • È necessario disporre delle autorizzazioni di scrittura per alcune destinazioni idonee.

Per chi è interessato ai dettagli, è possibile esaminare, https://github.com/okomarov/tableutils. Specificamente lo install_tableutils (il file potrebbe non essere aggiornato).

0

A seconda dell'utilizzo della nuova classe, forse si potrebbe seguire un approccio più pulito. L'approccio proposto descritto nel tuo post ha l'inconveniente che forse il codice utilizzato nel tuo ambiente aggiornato non sarebbe facilmente trasferibile in un nuovo ambiente, o un programma eseguito nel tuo ambiente potrebbe dimostrare un comportamento diverso in un ambiente diverso.

Alcune domande che potresti prendere in considerazione (e forse chiarire) potrebbero essere: come intendi utilizzare la nuova classe? Vuoi sostituire tutti gli usi della tabella esistente? Vuoi essere in grado di usarlo al posto di un argomento di classe tabella? Oppure si desidera modificare la tabella in modo che ogni utilizzo della classe della tabella originale nel proprio ambiente utilizzi la nuova classe.

Se hai solo bisogno di una nuova tabella migliorata per il tuo utilizzo, potresti considerare di incapsulare la classe della tabella originale in una nuova classe. E.g MyTable, delegare tutti i metodi che non sono necessari ai metodi della tabella originale, sostituire i metodi che si desidera migliorare o aggiungerne di nuovi.

Aggiornamento: ho appena visto la soluzione completa in Github e ho capito cosa intendevi fare. Bel lavoro. Lascerò il post nel caso qualcuno lo trovasse utile.

+0

Come dichiaro nella mia prima frase, la classe del tavolo è chiusa, quindi non posso creare una sottoclasse. Inoltre, non sono abbastanza sicuro di cosa intendi per "portatile in un nuovo ambiente". Dico che uno degli aspetti negativi della mia soluzione è la necessità esplicita di affrontare i cambiamenti nelle versioni MATLAB che riguardano la classe della tabella. Come per il sistema operativo, spetta a ciascun metodo preservare la compatibilità (quindi influisce su qualsiasi soluzione). L'uso che voglio fare è elencato nei punti 1 e 2 delle domande. – Oleg

+0

1. Con la frase "soluzione facilmente trasportabile in un nuovo ambiente" intendo "essere in grado di utilizzare la soluzione in un nuovo ambiente con il minimo sforzo possibile". Avendo visto la tua soluzione, penso che sia facilmente trasportabile. 2. Non intendevo sottoclasse tabella. Solo per creare una nuova classe (senza sottoclassare la "tabella" originale), creare firme di metodo identiche e aggiungere i propri metodi per poter utilizzare questa nuova tabella nel codice. Lo svantaggio sarebbe che non sarebbe una sottoclasse di tabella. Forse questa soluzione non ha tutte le proprietà che vuoi. –