matlab - 在 Octave 中重载内置函数时内置函数的行为不一致

标签 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(显然)会发出警告。如果您查看警告,您会发现对于函数重载有效和无效的警告,它们略有不同:

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 路径中时才起作用。

使用 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

关于matlab - 在 Octave 中重载内置函数时内置函数的行为不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37861252/

相关文章:

matlab - 阻止 MATLAB 在找不到我要打开的文件时创建新文件

unit-testing - TDD - 我应该为此功能编写哪些测试?

performance - 以更干净/更有效的方式过滤数据

python - SciPy 而不是 GNU Octave

matlab - ???索引超出矩阵尺寸PSD问题

image-processing - 如何在 MATLAB 中检查图像的类别?

arrays - 为什么当通过 ParamArray 将数组元素传递给函数时,函数中会到达 varpointer?

javascript - JS 函数返回函数,共享应该私有(private)的数据

octave - 如何在 Octave 中做偏导数

python - 使用 MNIST 数据集训练的 NN 和 CNN 数字识别前的预处理