如何写保护Matlab语言?

时间:2015-08-29 15:49:27

标签: matlab function syntax

Matlab允许您在没有警告的情况下覆盖内置函数。

例如,我用变量覆盖了函数max(),但Matlab并没有提醒我这一点。只有在调用函数时才会抛出错误,并且无法帮助您查看实际问题:

min     = 0;
max     = 10;
x       = linspace(min,max,20);
y       = exp(x);
disp(['the value is: ', num2str(max(y))])

错误讯息:

Subscript indices must either be real positive integers or logicals.

有没有办法在启动时或在设置文件中写保护所有Matlab语言以防止这种情况?

2 个答案:

答案 0 :(得分:4)

我不知道如何做你想做的事。但是有一种方法可以使用which通过变量或其他函数检查特定函数是否被阴影:即分析which(fname, '-all')的输出,其中fname是一个包含函数名称的字符串。

max函数为例:比较(无阴影)

>> 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

在第二种情况下,which(fname, '-all')告诉您max是一个隐藏多种方法的变量。

因此,要测试阴影是否正在发生,

  1. which(fname, '-all')的输出分配给变量。

    原则上,这可以s = which(fname, '-all');完成。然而不幸的是,这会产生不同的输出;特别是,上面行中的% ...部分(告知是否有阴影)被删除:

    >> 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'
    

    因此,我们需要求助于evalc以获得完整的输出:s = evalc('which(fname, ''-all'')');。结果s是一个长字符串,其中包含换行符分隔的所有行(包括% ...部分):

    >> 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
    
  2. 分析在步骤1中获取的字符串s,看它是否包含'% Shadowed'。这可以通过strfind轻松完成:即如果有阴影,strfind(s, '% Shadowed')将为非空。

  3. 总结

    全部放在一起,

    isShadowed = ~isempty(strfind(evalc('which(fname, ''-all'')'), '% Shadowed'));
    
    如果变量true中包含名称的函数被遮蔽,则

    返回fname,否则返回false

    变量示例

    >> 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
    

    具有指定功能的示例

    在文件std.m中创建一个函数并将其放在路径中。这将影响Matlab的std函数。

    >> fname = 'std';
    >> isShadowed = ~isempty(strfind(evalc('which(fname, ''-all'')'), '% Shadowed'))
    isShadowed =
         1
    

    现在删除功能文件(或从路径中删除其文件夹):

    >> fname = 'std';
    >> isShadowed = ~isempty(strfind(evalc('which(fname, ''-all'')'), '% Shadowed'))
    isShadowed =
         0
    

    匿名函数示例

    >> 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
    

答案 1 :(得分:1)

截至2015年9月,我还没有找到一种方法轻松写保护原生matlab函数/语言,作为启动时的设置/标志/等。

如果您担心特定功能,可以通过多种方式查看它们是否被隐藏,包括Luis Mendo的回答:which('name_of_function', '-all')

如果将来找到某种方法,我很乐意接受这个答案!