Add a method to Matlab table class

2020-05-05 17:50发布

问题:

I wish to add a method called nansubset to the table class. Essentially it allows you to call T(r,c) where r and c are real positive integer vectors possibly containing NaN's.

Stubbed code for nansubset.m could be:

function T = nansubset(T, r, c)
T = T(r,c);
end    

I am following the instructions here, which detail how to add a new method to the cell class. Basically, in a folder on my Matlab path, I create a folder called @table, and within this folder, create a file called nansubset.m.

I am getting the following problems:

>> tmpT = table(); nansubset(tmpT, 1, 1)
Undefined function 'nansubset' for input arguments of type 'table'.

and

>> doc @table/nansubset
Your search - @table/nansubset - did not match any documents.

However:

edit nansubset

and

edit @table/nansubset

both open the method file in my editor.

Further, I followed the instructions in the above link to add the plus method to the cell class and find that it works perfectly.

Can someone please explain to me how I can add this additional method to the table class?

回答1:

With the release of Matlab R2012b (version 8), the class folder behavior changed (emphasis is mine):

In MATLAB Versions 5 through 7, class folders do not shadow other class folders having the same name, but residing in later path folders. Instead, the class the combination of methods from all class folders having the same name define the class. This is no longer true.

For backward compatibility, classes defined in class folders always take precedence over functions and scripts having the same name, even those that come before them on the path.

The combination of the two bold statements explains the behavior:

  • cell is a built-in Matlab function that predates the new OOP rules that returns an instance of its class. And before R2012b, adding methods to a class folder called @cell added the methods to the object returned from the cell function (which isn't defined with a classdef nor a class folder); this ability was retained for compatibility with legacy user code.
  • table was added after R2012b, is defined via a class folder, and is Sealed. Since it is Sealed, it cannot be subclassed. And with the new rules, any @table folder without an associated classdef file will not register as a class folder nor will its methods be composed into the existing class unless it is part of the legacy system (like cell).

I can see three workarounds listed in the order I think is best:

  1. Have a function on the Matlab path, just like the one you have, and always call the "method" using function notation instead of dot notation. If you need more "methods" group them in a folder or package (if good namespacing is desired) on the path. Since table is a value class, this option doesn't seem bad.
  2. Create a wrapper class like the one below. It is cumbersome but automatically encapsulates the additional functions.

    classdef MyTable < handle
    
        properties
            tab;
        end
    
        methods
            function mytab = MyTable(varargin)
                mytab.tab = table(varargin{:});
            end
            function tabnan = nansubset(mytab,r,c)
                tabnan = mytab.tab(r,c);
            end
        end  
    end
    
  3. Create a local copy of [matlabroot,'\toolbox\matlab\datatypes\@table\*'] and add the methods directly. I can't think of any huge drawbacks to this per se, but it feels weird copying internals like this.


标签: matlab oop