我试图在八度的内置功能过载,以在调用内置版本的过载函数之前执行自定义操作。在MATLAB(据说是八度)中,我可以使用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
现在,我在调试此事时注意到的一件事是,当您具有与内置的名称相同的功能时,八度(显然)发出警告。如果您查看警告,则它们的功能超载的警告略有不同,并且不适用于:
警告:函数./disp.m阴影一个内置的函数< - works
警告:函数./figure.m阴影核心库函数< - 不起作用
文档似乎没有在核心库函数和内置功能之间有任何区别,并且builtin
的文档中未提及此行为。
有人知道是什么原因导致这种行为,并且对我如何解决这个问题有任何建议?
builtin
仅适用于内置功能。正如您已经了解的那样,问题在于内置和核心库函数之间的区别。
内置函数内置在八度解释器本身中。
核心库函数是用八度分布的函数,其中包括但不限于内置功能。其他核心库功能包括用八度语言(M文件)编写的所有功能和动态链接的功能(OCT文件)。这些其他功能不是八度解释器的一部分,仅是因为它们的目录被添加到八度路径中。
使用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
在八度提示下行为不同。独立于此,您可以在.octaverc
上定义阴影功能:
$ tail -n 5 ~/.octaverc
function varargout = figure (varargin)
mlock ();
disp ("here");
[varargout{1:nargout}] = builtin ("figure", varargin{:});
endfunction
$ octave
octave> figure
here