2015-08-29 3 views
9

Matlab позволяет вам перезаписывать встроенные функции без предупреждения.Как я могу защищать язык 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 при запуске или в файле настроек, чтобы предотвратить это?

+3

Интересный вопрос. Что вам нужно, если вы наберете 'max = 3'? Ошибка, ничего, предупреждение ...? Вы всегда можете гарантировать, что вы запустили встроенную функцию, используя 'builtin', как это' x = builtin ('max', [- 4, 3]) ', но это, конечно, очень громоздко. _Убедитесь, что не перегрузите 'встроенный' (http://stackoverflow.com/a/18360748/2338750) !! _ –

+0

Ну ... ошибка/предупреждение при перезаписывании будет приятной. Так будет уведомление в интерактивном редакторе. Приятно знать функциональность 'builtin', но я бы, вероятно, просто изменил имя переменной. – ConfusinglyCuriousTheThird

+1

Я думаю, это невозможно. Может быть, только при перегрузке ** каждого ** одного фундаментального класса в Matlab http://de.mathworks.com/help/matlab/matlab_prog/fundamental-matlab-classes.html Но я не рекомендую его. Это может сделать Matlab бесполезным, когда вы делаете это неправильно. Но вы всегда можете проверить с помощью '>> exist possible_var_name', если он уже существует. '>>, который something_that_exist' сообщает вам, откуда он или что это такое. – Markus

ответ

1

По состоянию на 9/2015, Я не нашел способ легко написать защищать родные функции/язык matlab, как параметр/flag/etc at s tartup.

Если вас беспокоит какая-либо конкретная функция, существуют различные способы увидеть, затенены ли они, включая ответ Луиса Мендо: which('name_of_function', '-all').

Если метод найден в будущем, я с радостью приму этот ответ!

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 

с (затенения)

>> 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. Анализ строки s, полученного на стадии 1, чтобы увидеть, если он содержит '% Shadowed'. Это легко сделать с помощью strfind: именно, strfind(s, '% Shadowed') будет непустым, если есть затенение.

В заключении:

Собирает все вместе,

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

Спасибо Luis. Это хорошая информация, но это не совсем то, что я ищу: /. Я надеялся, что есть элегантное решение, скажем, флаг «-здесь» или предпочтение, которое я мог бы изменить, чтобы изменить поведение Matlab. Это полезно, если функция уже перезаписана. – ConfusinglyCuriousTheThird

+0

Да, я знаю.То, что вы хотите, было бы интересно достичь –

Смежные вопросы