2012-02-24 5 views
8

私の機能の中には、いくつかの警告をエラーに変換したいものがあります。私はstr2funcMATLAB: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 - あなたの方法は一つだけです。 –

答えて

1

:それは私に私の例を変更することができます。あなたはまた、として、警告の詳細infomrat6ionを取得するには、warning on stacktraceで見ることができ

dbstop if warning 

または

dbstop if warning MyFunc:InvalidFunctionName 

:警告にエラーをオンにしたいためのあなたの理由に応じて、あなたがすることによって得ることができるかもしれません彼らは現れる。

実際のエラーメッセージ(デバッガに侵入する方法だけではありません)が必要な場合、私は実際にあなたが質問に含める方法にかなり感心しています。

0

これをやや一般化する方法が見つかりました。 setwarnings2errorsgetwarnings2errors

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

、彼らはスロー最後の警告である場合にエラーがスローされます設定されているすべての警告:それは(tictocと同様に)、以下のように動作します。したがって、多くの異なる警告が発生する大きなブロックでは使用しないでください。

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( '追加コマンドラインからのUSAGE '、' MATLAB:str2func:invalidFunctionName ')

警告。M:

% 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 
関連する問題