我试图重载 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(显然)会发出警告。如果您查看警告,您会发现对于函数重载有效和无效的警告,它们略有不同:
warning: function ./disp.m shadows a built-in function <-- WORKS
warning: function ./figure.m shadows a core library function <-- DOES NOT WORK
文档似乎没有对核心库函数和内置函数进行任何区分,并且 builtin
的文档中也没有提及此行为。
有谁知道导致此行为的原因,并对如何解决此问题有任何建议吗?
最佳答案
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
关于matlab - 在 Octave 中重载内置函数时内置函数的行为不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37861252/