In numerous functions that I wrote over the years, some input arguments were expected to be strings in the old sense, i.e. char arrays for example, 'on'
or 'off'
. Matlab release R2016b introduced the concept of string objects, which can be created using the string function or [starting in R2017a] double quotes ("on"
).
The problem is that I have numerous functions that supported the old char-based strings but not the new string objects. If someone tries to enter a string object ("on"
) as input to a function that expects a char-array ('on'
), in many cases Matlab will error. This by itself is very unfortunate – I would have liked everything to be fully backward-compatible. But unfortunately this is not the case: MathWorks did invest effort in making the new strings backward-compatible to some degree (for example, graphic object property names/values and many internal functions that now accept either form as input). However, backward compatibility of strings is not 100% perfect.
In such cases, the only solution is to make the function accept both forms (char-arrays and string objects), for example, by type-casting all such inputs as char-arrays using the builtin char function. If we do this at the top of our function, then the rest of the function can remain unchanged. For example:
function test(stage) if isa(stage,'string') stage = char(stage); end % from this point onward, we don't need to worry about string inputs - any such strings will become plain-ol' char-arrays switch stage case 'stage 1', ... case 'stage 2', ... ... end end
That was simple enough. But what if our function expects complex inputs (cell-arrays, structs etc.) that may contain strings in only some of their cells/fields?
Luckily, Matlab contains an internal utility function that can help us: controllib.internal.util.hString2Char. This function, whose Matlab source-code is available (%matlabroot%/toolbox/shared/controllib/general/+controllib/+internal/+util/hString2Char.m) recursively scans the input value and converts any string object into the corresponding char-array, leaving all other data-types unchanged. For example:
>> controllib.internal.util.hString2Char({123, 'char-array', "a string"}) ans = 1×3 cell array {[123]} {'char-array'} {'a string'} >> controllib.internal.util.hString2Char(struct('a',"another string", 'b',pi)) ans = struct with fields: a: 'another string' b: 3.14159265358979
In order to keep our code working not just on recent releases (that support strings and controllib.internal.util.hString2Char) but also on older Matlab releases (where they did not exist), we simply wrap the call to hString2Char within a try–catch block. The adaptation of our function might then look as follows:
function test(varargin) try varargin = controllib.internal.util.hString2Char(varargin); catch, end % from this point onward, we don't need to worry about string inputs - any such strings will become plain-ol' char-arrays ... end
Note that controllib.internal.util.hString2Char is a semi-documented function: it contains a readable internal help section (accessible via help controllib.internal.util.hString2Char
), but not a doc-page. Nor is this function mentioned anywhere in Matlab’s official documentation. I think that this is a pity, because it’s such a useful little helper function.