用于函数顺序评估的本机 MATLAB 函数?



所以我试图在 MATLAB 函数中完善我的输入验证,在这个过程中,我最终创建了以下函数,它真正使我的代码更干净。我把它完整地放在这里,以防有人觉得它有用:

function [] = callFunctions(varargin)
%callFunctions Calls a sequence of functions on their respective arguments.
%   The inputs are expected as funcHdl1, {input1}, funcHdl2, {input2}, ...
%   Then callFunctions calls sequentially func1(input1); func2(input2); ...
%% === INPUT VALIDATION ===
% Check that the callFunctions has at least one argument
message = 'The number of arguments must be positive.';
assert(nargin > 0, message);
% Check that the callFunctions has an even number of arguments
message = 'The number of arguments must be even.';
assert(mod(nargin,2)==0,message);
% Name the handles
numHandles = nargin/2;
handleNames = cell(1,numHandles);
inputNames = cell(1,numHandles);
for k=1:numHandles
handleNames{k} = 'handle';
handleNames{k} = cat(2, handleNames{k}, int2str(k));
inputNames{k} = 'input';
inputNames{k} = cat(2, inputNames{k}, int2str(k));
end
% Function to check that the inputs are function handles
isValidFunctionHdl = @(x) validateattributes(x, {'function_handle'}, {});
% Create an input parser
p = inputParser;
% Add all arguments to check if they are handles. Don't check the inputs.
for k=1:numHandles
p.addOptional(handleNames{k}, 0, isValidFunctionHdl);
p.addOptional(inputNames{k}, 0);
end
% Parse the input
p.parse(varargin{:});

%% === PROGRAM ===
% Evaluate all the functions on their inputs
for k=1:numHandles
feval(varargin{2*k-1},varargin{2*k}{:}); 
end
end

现在称为%% === PROGRAM ===的最后一部分是重要的部分。它只是评估func1, func2, func3, ...在它们各自的输入input1, input2, input3, ...上的函数,所有这些函数都作为callFunctions的输入给出。它被称为:

callFunctions(funcHdl1, {input1}, funcHdl2, {input2}, ...)

我的问题很简单:是否有一个原生的 MATLAB 函数可以执行callFunctions所做的事情?我在输入验证期间使用它(与assertvalidateattributes结合使用)。所以 Ì 打算在我编写的几乎每个函数中使用callFunctions。我想为此使用尽可能少的自定义函数。

编辑:我不想进入这个以保持帖子简短。但是,是的,在这种情况下,这对我来说似乎是必要的。这是我使用输入解析器进行输入验证的时候。我经常需要检查多个条件,例如(完全虚构的示例):

% Made up function to illustrate context
function [] = myFunction(input)
% Create an input parser
p = inputParser;
% Create functions to validate input. Must be a 2d logical array with at least one false value
isValidArray = @(x) validateattributes(x, {'logical'}, {'2d'});
hasAtLeastOneFalse = @(x) assert(length(find(x)) < length(x), 'Must be at least one false.');
isValidInput = @(x) callFunctions( isValidArray, {x}, hasAtLeastOneFalse, {x} );
% Add the required input
p.addRequired('input', isValidInput);
% Parse the input
p.parse(input);
end

这使我的代码更加干净,因为它允许我在调用addRequired时组合多个validateattributesassert语句。

据我所知,没有这样的东西已经存在......我不确定为什么会有。

基本上你正在交易这个:

func1(input1);
func2(input2);

为此:

callFunctions(@func1, {input1}, @func2, {input2})

我看到的只是一堆输入检查是否正确使用了callFunctions。 假设每个单独的函数都写得很好并且有自己的断言等......我根本不需要这个。 除了使阅读更难。

您可以完全跳过它,或者只是为FCN句柄和输入列表提供一个简单的for循环。 每个函数都会处理自己的错误,你不会围绕看起来很简单的东西添加一堆代码。

编辑:到您的示例用法:为什么不做这样的事情? 对我来说,这比你的例子要"干净"得多,这似乎是你的目标。

function [] = myFunction(input)
% Create an input parser
p = inputParser;
% Must be a 2d logical array with at least one false value
addRequired(p, 'input', @(x) validateattributes(x, {'logical'}, {'2d'}));
p.parse(input);
assert(length(find(input)) < length(input), 'Must be at least one false.')
disp('Running rest of code with good inputs!')

它可以处理所有错误输入的情况:

>> myFunction(ones(2,2,2))
Error using myFunction (line 6)
The value of 'input' is invalid. Expected input to be
one of these types:
logical
Instead its type was double.
>> myFunction(true(2,2,2))
Error using myFunction (line 6)
The value of 'input' is invalid. Expected input to be two-dimensional.
>> myFunction(true(1,2))
Error using myFunction (line 7)
Must be at least one false.
>> myFunction([true false])
Running rest of code with good inputs!

最新更新