2016-01-23 30 views
17

SETUP Win7的64B,R2015b,16 GB的RAM,CPU i7-2700MATLAB:壓倒一切的表()方法

table()fundamental Matlab class這也是密封,因此我不能子類它。

我要修復這個類的一些方法和增加新的的。例如,table.disp()基本上被破壞,例如,請嘗試NOT disp(table(rand(1e7,1))),或在命令窗口中忘記;。該變量在RAM中只佔76 MB,但顯示器無緩衝,並且會導致系統失速!

  1. 我可以覆蓋方法,如table.disp()沒有寫入到matlabroot\toolbox\matlab\datatypes\@table
  2. 我可以擴展表類用C:\MATLAB\@table\ismatrixlike.m下的新方法嗎?爲什麼我得到

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

    很顯然,我沒有

    addpath C:\MATLAB\ 
    rehash toolboxcache 
    

    我也試過clear all

    該路徑具有(字母)優先於matlabroot,但缺少table.m類定義。如果我將本地課程補習添加到C:\MATLAB\@table,那麼我可以運行我的新補習方法(在clear all之後)。但是:

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

    只列出了新\@table文件夾的方法,即使(某些)的老方法仍然可以工作,例如

    size(table) 
    

    這部分地解決了這個問題,因爲現在,本地\@table\private文件夾不能訪問了,因此許多本地方法被打破!

我爲什麼要這樣做?因爲我不想在table()修好之前再等兩年。我已經失去了整整一天,因爲我在命令窗口中簡單地忘記了;,並且如果它正在運行多天模擬,我無法強制在我的電腦上重新啓動,但是我必須等待磁盤交換結束:(。。

附錄 更多方面有關disp(table(rand(1e7,1)))這是當我打它會發生什麼(幸運的是我不夠快,CTRL-C出來的)。

enter image description here

罪魁禍首是線的table.disp() 172將數字數組轉換爲一個單元格字符串(使用填充也是!):

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

讓Matlab做任何已經在工具箱中不存在的東西......保證疼痛。放棄所有希望,誰進入這裏! – hoosierEE

+0

請注意'istable'不是表類的方法,而是它自己的函數,它調用'isa(t,'table')'。 – Suever

+0

@Suever感謝您注意到這一點。我會將它改爲'table.size()' – Oleg

回答

1

對我來說,以下工作:

  1. 定義修改disp功能,說disp_modified.m,如下,並把它放在你的路徑:

    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. 定義disp作爲function handle修改過的功能(您可以在startup.m中做到這一點,默認情況下始終有它):

    disp = @disp_modified; 
    

在此之後,在命令窗口中,我得到

>> 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

這需要你明確地調用'disp'。我相信他想要將table的內部調用重載到disp中,這將始終(不管你的本地函數是什麼)使用內置的disp。這至少是防止在您省略分號時發生的情況。 – Suever

+0

這個解決方案相當不好。它不會通過缺少';'來攔截隱含的'disp()',並且可能鼓勵一個危險的練習。此外,它不是可擴展和臨時的。 「清除」後應該怎麼做?重新定義每種方法的所有顯式變量? – Oleg

+0

而不是調用函數「disp_modified」,你可以稱之爲「disp」,那麼它不會被清除。 – Daniel

2

與幾個替代試驗後,我採取了intereferes最少,Matlab的本地@table實施解決方案,它很容易,如果去除事情出錯了。

解決辦法:

  • 副本整個@table文件夾,即fullfile(matlabroot,'toolbox','matlab','datatypes','@table'),成目的地自帶字母順序@table文件夾之前(見Class Precedence and MATLAB Path),並在其上具有寫權限。

    我選擇了目的地fullfile(matlabroot,'toolbox','local','myfiles'),因爲我沒有與操作系統的交叉兼容性打擾,即matlabroot需要照顧,對我。

  • 目的地你的整個文件夾@table用新的,超載和壓倒一切的方法。

  • add the destination to the matlab path。

效果,優點和缺點:

  • 現在的天然@table類/方法的陰影,嘗試例如which table -all。但是,這種效果非常明顯,易於檢測和輕鬆移除(刪除命令和刪除路徑);
  • 原生@table(現在被遮蔽)和新@table之間沒有奇怪的衝突;
  • 所有新舊方法都可見,請嘗試methods(table);
  • 私人表格的方法可以訪問...
  • ...但你不得不使用它們。
  • 將新方法(用戶實現)暴露給私有方法需要更多維護並直接處理表實現中的版本衝突。
  • 您需要在某些符合條件的目標位置寫入權限。

對於那些有興趣的細節,你可以看看,https://github.com/okomarov/tableutils。特別是install_tableutils(自述文件可能不會更新)。

0

根據新班級的使用情況,也許你可以採用更清潔的方法。在您的文章中描述的建議方法的缺點是,您的更新環境中使用的代碼可能無法輕鬆移植到新環境中,或者在您的環境中執行的程序可能會在不同的環境中顯示不同的行爲。

你可以考慮的一些問題(也許可以澄清)是:你打算如何使用新課堂?你想替換所有現有的表格用途嗎?你想能夠使用它而不是表類參數嗎?或者你是否想改變表格,以便環境中原始表類的每個用法都使用新類。

如果你只是需要一個新的改進表用於你的使用,你可以考慮將原始表類封裝在一個新類中。例如MyTable,將您不需要的所有方法委託給原始表方法,替換您想要改進的方法或添加新方法。

更新:剛剛在Github上看到了完整的解決方案,並理解您打算做什麼。工作很好。我會離開帖子,以防有人發現它有用。

+0

正如我在第一句話中所述,表類是封閉的,因此我不能繼承它。另外,我不太清楚「移植到新環境」的含義。我確實說我的解決方案的缺點之一是明確需要處理影響表類的matlab版本中的更改。根據操作系統,每種方法都要保持兼容性(所以它影響任何解決方案)。我想要做的用途列在問題的第1點和第2點。 – Oleg

+0

1.通過短語「解決方案輕鬆移植到新環境中」,我的意思是「能夠儘可能以最少的努力在新環境中使用您的解決方案」。看到你的解決方案,我認爲它很容易移植。 2.我不是故意要表子類。只需創建一個新類(不需要對原始「表」)進行子分類,就可以創建相同的方法簽名,並添加自己的方法以便能夠在代碼中使用這個新表。缺點是它不會是表的子類。也許這個解決方案沒有你想要的所有屬性。 –