在Octave

时间:2016-06-16 13:50:45

标签: matlab function octave overloading

我试图在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的文档中未提及此行为。

有没有人知道导致此行为的原因,并对如何解决此问题有任何建议?

1 个答案:

答案 0 :(得分:4)

builtin仅适用于内置函数。正如您已经了解的那样,问题在于内置库和核心库函数之间的区别。

内置函数内置于Octave解释器中。

核心库函数是与Octave一起分发的函数,包括但不限于内置函数。其他核心库函数包括用Octave语言(m文件)和动态链接函数(oct文件)编写的所有函数。这些其他函数不是Octave解释器的一部分,只能将它们的目录添加到Octave路径中。

使用whichexist查看功能是否内置:

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