是否可以围绕与原始函数具有完全相同名称的函数创建包装器?
这在用户希望在将输入变量传递给内置函数之前对输入变量进行一些额外检查的情况下非常有用如何在 MATLAB IDE 挂起显示非常大的数组时中断它?
是否可以围绕与原始函数具有完全相同名称的函数创建包装器?
这在用户希望在将输入变量传递给内置函数之前对输入变量进行一些额外检查的情况下非常有用如何在 MATLAB IDE 挂起显示非常大的数组时中断它?
实际上,除了 slayton 的答案,您不需要使用openvar
. 如果您定义一个与 matlab 函数同名的函数,它将隐藏该函数(即被调用)。
为了避免递归调用您自己的函数,您可以使用builtin
.
例如
outputs = builtin(funcname, inputs..);
rand.m
简单的例子,在matlab路径中命名为:
function out = main(varargin)
disp('Test wrapping rand... calling rand now...');
out = builtin('rand', varargin{:});
请注意,这仅适用于由 找到的函数builtin
。对于那些不是,slayton 的方法可能是必要的。
是的,这是可能的,但它需要一些黑客攻击。它要求您复制一些函数句柄。
使用问题中提供的示例,我将展示如何将函数包装openvar
在用户定义的函数中,该函数检查输入变量的大小,然后允许用户取消对太大变量的任何打开操作。
此外,当用户双击 Matlab IDE 的工作区窗格中的变量时,这应该可以工作。
我们需要做三件事。
openvar
函数的句柄openvar
openvar
名称重定向到我们的新函数。示例函数
function openVarWrapper(x, vector)
maxVarSize = 10000;
%declare the global variable
persistent openVarHandle;
%if the variable is empty then make the link to the original openvar
if isempty(openVarHandle)
openVarHandle = @openvar;
end
%no variable name passed, call was to setup connection
if narargin==0
return;
end
%get a copy of the original variable to check its size
tmpVar = evalin('base', x);
%if the variable is big and the user doesn't click yes then return
if prod( size( tmpVar)) > maxVarSize
resp = questdlg(sprintf('Variable %s is very large, open anyway?', x));
if ~strcmp(resp, 'Yes')
return;
end
end
if ischar(x) && ~isempty(openVarHandle);
openVarHandle(x);
end
end
一旦定义了这个函数,那么你只需要执行一个脚本
openvar
openVarWrapper
脚本来设置连接openVar
指向openVarWrapper
示例脚本:
clear openvar;
openVarWrapper;
openvar = @openVarWrapper;
最后,当你想清理所有东西时,你可以简单地调用:
clear openvar;
我更喜欢 jmetz 的方法builtin()
,因为它可以应用,因为它很干净而且切中要害。不幸的是,很多很多功能都没有找到builtin()
。
我发现我能够使用which -all
和cd
命令的组合来包装一个函数。我怀疑这种方法可以适用于各种各样的应用程序。
在我的示例案例中,我想(暂时)包装interp1
函数,以便我可以检查 NaN 输出值。(interp1
默认情况下,该函数将在某些条件下返回 NaN,例如,如果查询点大于最大样本点。)这是我想出的:
function Vq = interp1(varargin)
persistent interp1_builtin;
if (isempty(interp1_builtin)) % first call: handle not set
toolbox = 'polyfun';
% get a list of all known instances of the function, and then
% select the first such instance that contains the toolbox name
% in its path
which_list = which('interp1','-all');
for ii = 1:length(which_list)
if (strfind(which_list{ii}, [filesep, toolbox, filesep]))
base_path = fileparts(which_list{ii}); % path to the original function
current_path = pwd;
cd(base_path); % go to the original function's directory
interp1_builtin = @interp1; % create a function handle to the original function
cd(current_path); % go back to the working directory
break
end
end
end
Vq = interp1_builtin(varargin{:}); % call the original function
% test if the output was NaN, and print a message
if (any(isnan(Vq)))
dbstack;
disp('ERROR: interp1 returned a NaN');
keyboard
end
end