Matlab allows you to overwrite built in functions without so much as a warning.
For example, I've overwritten the function max()
with a variable, but Matlab doesn't alert me to this. An error is only thrown later when the function is called, and doesn't help you see the actual problem:
min = 0;
max = 10;
x = linspace(min,max,20);
y = exp(x);
disp(['the value is: ', num2str(max(y))])
Error message:
Subscript indices must either be real positive integers or logicals.
Is there a way to write-protect all of the Matlab language at startup, or in a settings file to prevent this?
I don't know a way to do what you want. But there's a way to check if a specific function has been shadowed, either by a variable or by other function, using which
: namely, analyze the output of which(fname, '-all')
, where fname
is a string containing the function name.
Take the max
function as an example: compare (no shadowing)
>> clear all
>> fname = 'max';
>> which(fname, '-all')
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@logical\max) % logical method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@char\max) % char method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@double\max) % double method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint8\max) % uint8 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint16\max) % uint16 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint32\max) % uint32 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint64\max) % uint64 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int8\max) % int8 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int16\max) % int16 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int32\max) % int32 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int64\max) % int64 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@single\max) % single method
C:\Program Files\MATLAB\R2010b\toolbox\matlab\timeseries\@timeseries\max.m % timeseries method
C:\Program Files\MATLAB\R2010b\toolbox\distcomp\parallel\@codistributed\max.m % codistributed method
C:\Program Files\MATLAB\R2010b\toolbox\shared\statslib\@ordinal\max.m % ordinal method
with (shadowing)
>> fname = 'max';
>> max = 10;
>> which(fname, '-all')
max is a variable.
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@logical\max) % Shadowed logical method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@char\max) % Shadowed char method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@double\max) % Shadowed double method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint8\max) % Shadowed uint8 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint16\max) % Shadowed uint16 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint32\max) % Shadowed uint32 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint64\max) % Shadowed uint64 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int8\max) % Shadowed int8 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int16\max) % Shadowed int16 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int32\max) % Shadowed int32 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int64\max) % Shadowed int64 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@single\max) % Shadowed single method
C:\Program Files\MATLAB\R2010b\toolbox\matlab\timeseries\@timeseries\max.m % Shadowed timeseries method
C:\Program Files\MATLAB\R2010b\toolbox\distcomp\parallel\@codistributed\max.m % Shadowed codistributed method
C:\Program Files\MATLAB\R2010b\toolbox\shared\statslib\@ordinal\max.m % Shadowed ordinal method
In the second case, which(fname, '-all')
tells you that max
is a variable that is shadowing several methods.
So, to test if shadowing is taking place,
Assign the output of which(fname, '-all')
to a variable.
In principle this could be done as s = which(fname, '-all');
. Unfortunately, however, this produces a different output; in particular, the % ...
part in the lines above (which tells if there is shadowing) is removed:
>> fname = 'max';
>> s = which(fname, '-all')
s =
'variable'
'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@logical\max)'
'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@char\max)'
'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@double\max)'
'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint8\max)'
'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint16\max)'
'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint32\max)'
'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint64\max)'
'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int8\max)'
'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int16\max)'
'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int32\max)'
'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int64\max)'
'built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@single\max)'
'C:\Program Files\MATLAB\R2010b\toolbox\matlab\timeseries\@timeseries\max.m'
'C:\Program Files\MATLAB\R2010b\toolbox\distcomp\parallel\@codistributed\max.m'
'C:\Program Files\MATLAB\R2010b\toolbox\shared\statslib\@ordinal\max.m'
So we need to resort to evalc
to get the full output: s = evalc('which(fname, ''-all'')');
. The result s
is a long string containing all lines (including the % ...
parts) separated by line feed characters:
>> fname = 'max';
>> s = evalc('which(fname, ''-all'')')
s =
max is a variable.
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@logical\max) % Shadowed logical method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@char\max) % Shadowed char method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@double\max) % Shadowed double method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint8\max) % Shadowed uint8 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint16\max) % Shadowed uint16 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint32\max) % Shadowed uint32 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@uint64\max) % Shadowed uint64 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int8\max) % Shadowed int8 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int16\max) % Shadowed int16 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int32\max) % Shadowed int32 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@int64\max) % Shadowed int64 method
built-in (C:\Program Files\MATLAB\R2010b\toolbox\matlab\datafun\@single\max) % Shadowed single method
C:\Program Files\MATLAB\R2010b\toolbox\matlab\timeseries\@timeseries\max.m % Shadowed timeseries method
C:\Program Files\MATLAB\R2010b\toolbox\distcomp\parallel\@codistributed\max.m % Shadowed codistributed method
C:\Program Files\MATLAB\R2010b\toolbox\shared\statslib\@ordinal\max.m % Shadowed ordinal method
Analyze the string s
obtained in step 1 to see if it contains '% Shadowed'
. This is easily done with strfind
: namely, strfind(s, '% Shadowed')
will be non-empty if there is shadowing.
In conclusion:
Putting it all together,
isShadowed = ~isempty(strfind(evalc('which(fname, ''-all'')'), '% Shadowed'));
returns true
if the function with name contained in variable fname
is shadowed, and false
otherwise.
Example with a variable:
>> clear all
>> fname = 'max';
>> max = 10;
>> isShadowed = ~isempty(strfind(evalc('which(fname, ''-all'')'), '% Shadowed'))
isShadowed =
1
>> clear max
>> isShadowed = ~isempty(strfind(evalc('which(fname, ''-all'')'), '% Shadowed'))
isShadowed =
0
Example with a named function:
Create a function in file std.m
and place it in your path. This will shadow Matlab's std
function.
>> fname = 'std';
>> isShadowed = ~isempty(strfind(evalc('which(fname, ''-all'')'), '% Shadowed'))
isShadowed =
1
Now delete the function file (or remove its folder from the path):
>> fname = 'std';
>> isShadowed = ~isempty(strfind(evalc('which(fname, ''-all'')'), '% Shadowed'))
isShadowed =
0
Example with an anonymous function:
>> std = @(x) x+1;
>> fname = 'std';
>> isShadowed = ~isempty(strfind(evalc('which(fname, ''-all'')'), '% Shadowed'))
isShadowed =
1
>> clear std
>> isShadowed = ~isempty(strfind(evalc('which(fname, ''-all'')'), '% Shadowed'))
isShadowed =
0
As of 9/2015, I have not found a way to easily write protect native matlab functions/language, as a setting/flag/etc at startup.
If you are concerned about a particular function, there are various ways to see if they are shadowed, including Luis Mendo's answer: which('name_of_function', '-all')
.
If a method is found in the future, I will gladly accept that answer!