MATLAB: Does cellfun provide different results when calling ‘size’ or @size on a cell array

arraycellcellfunclassdifferentisemptyMATLABmethodobjectoutputoverloadresultssize;table

I obtain different results for a table inside of a cell array, depending on whether I make use of 'size' or @size:
>> a = {table}
a =
1×1 cell array
{0×0 table}
>> cellfun('size',a,1)
ans =
1
>> cell2mat(cellfun(@size, a, 'UniformOutput', 0))
ans =
0 0

Best Answer

Both ways of using the "size" function provide different results. This is because the use of string functions has been maintained as legacy syntax, in order to preserve backward compatibility with older versions of MATLAB. However, their use is discouraged as it may lead to confusion.
This behavior is expected for some special functions, which can be found in the documentation link below:
Some of these are: 'isempty', 'islogical', 'isreal', 'length', 'ndims', 'prodofsize', 'size', or 'isclass'. As an illustrative example, see below a sample code in which this behavior is shown for the 'isempty' function:
>> a = {table} % Create a cell array containing an empty table.
a =
1×1 cell array
{0×0 table}
>> cellfun(@isempty,a) % Correct result: the table is empty.
ans =
logical
1
>> cellfun('isempty',a) % Confusing result.
ans =
logical
0
This happens for objects (as it is the case of tables), because they overload the function methods mentioned above. This is the reason why the use of the function handles is encouraged: if you specify a function name rather than a function handle, 'cellfun' does not call any overloaded versions of the function.
Please note that "Table" is a class that defines a Data Type and it has its own "Size" method overloaded. It provides the user with a two-element numeric vector, of which the first element indicates the number of rows, and the second element specifies the number of table variables. You can find a link to the documentation referring to this below:
Please be aware that this does not only happen for tables. In fact, this is valid for classes and timetables too. As an example, you can create an example class on a script file "myClass.m", as follows:
classdef myClass
methods
function size(obj)
disp('Test class')
end
end
end
In this class, the 'size' method has been overloaded to display dummy text instead. You can check how different results are obtained by running:
>> b = {myClass}
b =
1×1 cell array
{1×1 myClass}
>> cellfun('size',b,1) % Size string function.
ans =
1
>> cellfun(@size,b) % Overridden method.
Test class
Again, please note that calling the functions as a character vector or string array inside "cellfun" is not a recommended workflow but it is available only for legacy purposes.