2012-02-24 21 views
8

在我的一些函数中,我想将一些警告转换为错误。例如,如果我想在str2func产生一个MATLAB:str2func:invalidFunctionName警告抛出一个错误,我会做到以下几点:将警告转换为MATLAB中的错误

invalid_func_id = 'MATLAB:str2func:invalidFunctionName'; 
%hide warning of interest 
warning('off', invalid_func_id); 
%this might yield the warning of interest 
predicate_func_try = str2func(predicate_func); 
[~, warn_id] = lastwarn; 
assert(~strcmp(warn_id, invalid_func_id)... 
    , 'MyFunc:InvalidFunctionName'... 
    , 'The predicate function %s does not have a valid name'... 
    , predicate_func... 
    ); 
warning on all 

,如果我知道一个特定的代码块可以给一小部分警告这工作得很好。但是它很冗长,可能不会扩展到更大的代码块。有没有更好的方法来做到这一点?理想情况下,我想要一个功能,可以将某些警告转化为整个块中的错误。这将允许我修改我的示例:

warnings2errors('MATLAB:str2func:invalidFunctionName'); 
predicate_func_try = str2func(predicate_func); 
warnings2errors('off'); 
+3

根据这一线索 - http://www.mathworks.com/matlabcentral/newsreader/view_thread/158768 - 你的方式是唯一的一个。 – 2012-02-24 14:04:03

回答

1

我不知道干净的方法来完成你想要的。根据你的理由为希望把错误变成警告,你可能能够获得通过:

dbstop if warning 

dbstop if warning MyFunc:InvalidFunctionName 

你也可以看看warning on stacktrace,得到的警告更infomrat6ion他们出现了。

如果你需要一个实际的错误信息(不只是一种打入调试器的方式),那么我对你在问题中包含的方法印象深刻。

0

我找到了一种有点概括这种方式。它的工作方式如下(类似于tictoc):

warn_ids = setwarnings2errors('MATLAB:str2func:invalidFunctionName'); 
predicate_func_try = str2func(predicate_func); 
getwarnings2errors(warn_ids); 

之间setwarnings2errorsgetwarnings2errors,设置,如果他们抛出的最后警告会引发错误的所有警告。因此它不应该用于可能发生许多不同警告的大块中。我实现的功能方式如下:

setwarnings2errors:

function warning_ids = setwarnings2errors(varargin) 
warning_ids = cell(nargin, 1); 
for x_ = 1:nargin 
    local_arg = varargin{x_}; 
    assert(ischar(local_arg)); 
    evalin('caller', sprintf('warning off %s', local_arg)); 
    warning_ids{x_} = local_arg; 
end 
end 

getwarnings2errors:

function getwarnings2errors(warning_ids) 
[lastwarn_str, lastwarn_id] = evalin('caller', 'lastwarn'); 
num_warns = numel(warning_ids); 
try 
    for x_ = 1:num_warns 
     local_warn = warning_ids{x_}; 
     assert(~strcmp(local_warn, lastwarn_id)... 
      , lastwarn_id... 
      , lastwarn_str... 
      ); 
    end 
catch m_e 
    evalin('caller', 'warning on all'); 
    throwAsCaller(m_e); 
end 
evalin('caller', 'warning on all'); 
end 
5

另一种方法是超载警告本身。请参阅下面的warning.m和warning2error.m的实现。我从中看到的最大副作用是,您将在堆栈上看到一个额外的“warning.m”,以显示所有警告消息。不知道是否有解决办法。另外,你需要禁用MATLAB:dispatcher:nameConflict警告,因为我们超载了内建。

编辑:只是注意到了matlabcentral.com无证使用内置的警告,完成此: http://www.mathworks.com/matlabcentral/newsreader/view_thread/158768 http://undocumentedmatlab.com/blog/trapping-warnings-efficiently/

>> warning('error','MATLAB:str2func:invalidFunctionName') 

用法命令行

warning2error('加','MATLAB:str2func:invalidFunctionName')

警告。L:

% Overload of warning.m to enable conversion of certain warnings to errors 
% via warning2error.m 
% 
% Will want to disable warning "MATLAB:dispatcher:nameConflict" via command 
% warning('off','MATLAB:dispatcher:nameConflict'); 
% 
% Jesse Hopkins 
% Oct. 2 2012 

function varargout = warning(varargin) 
    %check for component:mnemonic syntax 
    if nargin >= 2 && ischar(varargin{1}) && any(regexp(varargin{1},'^(\w+:\w+){1,}$','start','once')) 
     %we've captured <component>[:<component>]:<mnemonic>syntax 

     %check if this is in the list 
     if warning2error('query',varargin{1}) 
      %YES, convert to error 
      ME = MException(varargin{1},varargin{2:end}); 
      ME = ME.addCause(MException('Warning2Error:ConvertedWarning','Converted warning "%s" to error becuase it was registered via warning2error.m.',varargin{1})); 
      ME.throwAsCaller; 
     end 
    end 

    %pass through to built-in warning 
    varargout{1:nargout} = builtin('warning',varargin{:}); 
end 

Warning2Error.m:

%warning2error.m 
%USAGE: 
% Add warnings to convert to errors. 
% warning2error('add','<component>[:<component>]:<mnemonic>',... 
% 
% Remove warnings to convert to errors 
% warning2error('remove','<component>[:<component>]:<mnemonic>',... 
% 
% Query warnings to convert to errors 
% tf = warning2error('query','<component>[:<component>]:<mnemonic>') 
% 
% Get entire list of warnings converted to errors 
% list = warning2error('get') 
% 
% Jesse Hopkins 
% Oct 2 2012 

function varargout = warning2error(op,varargin) 
    persistent list; 
    if isempty(list) 
     list = {}; 
    end 
    varargout={}; 

    switch lower(op) 
     case 'add' 
      list = unique([list(:);varargin(:)]); 
     case 'remove' 
      for i = 1:length(varargin) 
       [tf idx] = ismember(varargin{i},list); 
       allidx = 1:length(list); 
       newidx = setdiff(allidx,idx); 
       list = list(newidx); 
      end 
     case 'clear' 
      list = {}; 
     case 'get' 
      varargout{1} = list; 
     case 'query' 
      out = false(1,length(varargin)); 
      for i = 1:length(varargin) 
       out(i) = ismember(varargin{1},list); 
      end 
      varargout{1} = out; 
    end 
end