我试图在Octave中重载一些内置函数,以便在调用重载函数的内置版本之前执行自定义操作。在MATLAB(以及据称是Octave)中,我可以使用builtin
函数来完成此任务。
典型的函数定义看起来像这样,我在执行自定义操作后将所有输入/输出转发到内置/从内置转发:
function varargout = disp(varargin)
% Do a custom thing
fprintf('Calling overloaded disp!\n')
% Now call the builtin
[varargout{1:nargout}] = builtin('disp', varargin{:});
end
现在,如果我将此文件(disp.m
)放在我的路径上,则调用disp
的任何函数都将执行我的重载版本,该版本在调用内置disp
之前打印出额外信息功能
>> disp('hello world')
Calling overloaded disp!
hello world
我遇到的问题是,这适用于某些内置插件但不是全部。例如,如果我尝试重载figure
。
function varargout = figure(varargin)
disp('Creating a figure!')
[varargout{1:nargout}] = builtin('figure', varargin{:});
end
当我这样称呼时,builtin
再次调用重载函数而不是真正的内置函数。
>> figure()
Creating a figure!
Creating a figure!
Creating a figure!
...
error: max_recursion_depth exceeded
有趣的是,如果我将figure
重载为命令行函数而不是将其保存在figure.m
中,那么它的行为与我期望的完全一样。
> function varargout = figure(varargin), disp('here'), [varargout{1:nargout}] = builtin('figure', varargin{:}), endfunction
> figure()
here
现在我在调试时注意到的一件事是,当你有一个与内置函数同名的函数时,Octave(显然)会发出警告。如果您查看警告,它们对于重载功能有效并且不起作用的情况略有不同:
警告:函数./disp.m隐藏内置函数< - WORKS
警告:函数./figure.m隐藏核心库函数< - 不工作
文档似乎没有对核心库函数和内置函数进行任何区分,builtin
的文档中未提及此行为。
有没有人知道导致此行为的原因,并对如何解决此问题有任何建议?
答案 0 :(得分:4)
builtin
仅适用于内置函数。正如您已经了解的那样,问题在于内置库和核心库函数之间的区别。
内置函数内置于Octave解释器中。
核心库函数是与Octave一起分发的函数,包括但不限于内置函数。其他核心库函数包括用Octave语言(m文件)和动态链接函数(oct文件)编写的所有函数。这些其他函数不是Octave解释器的一部分,只能将它们的目录添加到Octave路径中。
使用which
或exist
查看功能是否内置:
octave> which disp
'disp' is a built-in function from the file libinterp/corefcn/pr-output.cc
octave> which figure
'figure' is a function from the file /home/carandraug/.local/share/octave/4.1.0+/m/plot/util/figure.m
octave> which audioread
'audioread' is a function from the file /home/carandraug/.local/lib/octave/4.1.0+/oct/x86_64-pc-linux-gnu/audioread.oct
octave> exist ("disp", "builtin")
ans = 5
octave> exist ("figure", "builtin")
ans = 0
octave> exist ("audioread", "builtin")
ans = 0
当然,没有承诺函数将在版本之间保持内置或m文件功能(尽管现实情况是这很少改变)。
请注意,Matlab中的逻辑是相同的,但内置函数集将是不同的。
现在我不理解的是,为什么builtin
在Octave提示符下表现不同。独立于此,您可以在.octaverc
:
$ tail -n 5 ~/.octaverc
function varargout = figure (varargin)
mlock ();
disp ("here");
[varargout{1:nargout}] = builtin ("figure", varargin{:});
endfunction
$ octave
octave> figure
here