Among the many changes that were introduced in R2012b, the new desktop understandably took the centerpiece, with the new documentation layout coming a close second. I already reported on a change to the online website that has gone largely unnoticed, which broke multiple links, causing much frustration.
Today I report on another such change, which has the potential of frustrating no fewer users. As in the online URLs change, this change was also not documented, only adding to the frustration. To the best of my knowledge, this particular case was first detected by chance and reported by Andreas Pomp in CSSM last week, although the change was apparently already introduced in R2012a:
In case that the first columns of your Excel table have only numeric numbers, then the command
[num,txt] = xlsread(...)returned in older Matlab releases for
txta cell array with blanks in the corresponding columns. In Release 2012b [sic – should be R2012a] these columns are missing at all. This has the consequence that column numbers must be changed if you read from cell array txt.
This caused some trouble in our code and I want to forward this warning to other users.
For example, let’s take the following simple Excel data file:
|R2011b and earlier||R2012a and later|
The response from Mathworks (1-K21ZFE) was:
It is certainly true that there is an inconsistency. If you use the syntax:
[num, txt] = xlsread('DeleteMe.xls','Sheet1','','basic');
you obtain the same outputs dimension as in the previous releases. Our documentation was not updated with the change of behavior in xlsread.
Note: the sheet-name is optional – you can specify
'' (an empty string) instead of
Unfortunately, this workaround leaves much to be desired.
The problem here is not only the missing documentation about the change in functionality. This is actually the lesser of the problems. The main issue is backward compatibility. A major function such as xlsread, which is widely used by numerous Matlab users and has remained stable for years, can not – MUST NOT! – change existing functionality, with or without proper documentation. Numerous Matlab programs rely on the existing functionality and behavior of xlsread. MathWorks cannot seriously expect thousands of Matlab users to change all their existing Matlab programs when upgrading to R2012a. And what if the program needs to work on both R2012a AND earlier Matlab releases, which do not accept the ‘basic’ input parameter? Or what if we need to use a range sub-set, which is unavailable in ‘basic’ mode? Adding insult to injury, this change was never documented in the release notes, nor in xlsread‘s doc page.
This tells us not to rely on the official release notes when deciding whether or not to upgrade. It causes such a maintenance headache that many users would simply prefer to remain with their older Matlab release, and not to upgrade. A real shame.
As an alternative to the official workaround above, I suggest modifying the %matlabroot%/toolbox/matlab/iofun/private/xlsreadSplitNumericAndText.m function, which is responsible for the functionality change. Specifically, comment line #45:
43: % Trim the leading and trailing empties from textData 44: emptyTextMask = cellfun('isempty', textData); 45: %textData = filterDataUsingMask(textData, emptyTextMask); % Comment out this line!
This will restore the previous functionality in one go, without having to modify any user programs. Of course, we would need to redo this fix in every future Matlab release as well. Still, considering the alternatives, this appears to be the best choice in my eyes.
While the case with xlsread seems to break a new record in backward-incompatibility, other similar cases have also been reported. One such recent issue was raised over the [this-time] documented removal of some functionality in the widely-used interp1 function. No fewer than 54 comments (and counting) were added within a few days of the initial CSSM post, which indicates the amount of frustration that such changes cause.
Looks like some people may have forgotten the first rule and top commandment of engineering:
OK, is this an exception? This MathWorks fix didn’t work for an XLSX file looking like:
>> [a,b] = xlsread('badcol.xlsx','Sheet1','')
1 NaN NaN NaN
2 4 5 6
3 4 5 6
4 4 5 6
'' 'a' 'b' 'c'
>> [a,b] = xlsread('badcol.xlsx','Sheet1','','basic')
1 NaN NaN NaN
2 4 5 6
3 4 5 6
4 4 5 6
'a' 'b' 'c'