从 Octave 中的私有函数访问私有函数 [BUG]

Access private functions from private functions in Octave [BUG]

在 Matlab 中,私有函数是那些存储在名称为 private 的子目录中的函数。他们有一个可见性限制:“您不能从命令行或私有文件夹父级之外的函数调用私有函数”(https://se.mathworks.com/help/matlab/matlab_prog/private-functions.html)。

编辑:Octave 试图遵循这个:“如果 func1 的路径是 directory/func1.m,并且如果func2在目录directory/private/func2.m下找到,那么func2只能用于使用 func1 等函数,这些函数位于 目录 中。” (https://octave.org/doc/v6.2.0/Private-Functions.html)

我正在使用 Octave 6.2。

我有几个函数想设为私有,比如 AB。它们有一些共同的部分,所以很自然地分离出这部分并创建另一个函数,比如 C,从 A 的内部调用和 B.

我把CAB放在同一个私有目录下,它似乎该语言不允许这种构造,因为我收到一条错误消息,指出 C 未定义。我发现它违反直觉,尽管如此,根据 Octave 文档的上述引用,这是可以预期的,它说私有函数只能从 parent 目录中看到。

我尝试在第一个子目录中放置一个嵌套的私有子目录(相对路径为“private/private”)作为解决方法,但它没有解决问题,我仍然收到未定义 C.

的错误

因此,从私有 AB 调用 C 的唯一方法似乎是是让它 public 可见,即使从代码架构的角度来看 C 不应该 public ,因为它仅由私有函数调用。另一种方法是在 AB 中保留 C 相同代码的副本 - 使用违反DRY原则的所有不良后果。

编辑:正如评论中所指出的,这个问题似乎是 Octave 特有的。在 Matlab 中,您可以从其他私有函数访问私有函数。

我的问题是:在 Octave 中维护私有函数公共部分的正确方法是什么?

EDIT2:问题确实似乎是当前版本 Octave 中的一个 bug 提供的 MWE 工作正常 除非...

我发现下面的序列是一个最小的-不是的工作示例,导致错误显式: 1) A.mC.m目录,A.m 调用 B.mB.mdirectory/private 中,最初 NOT 调用 C.mA 的评估工作正常。 2) 修改B.m调用CA 的评估仍然有效。 3) 将 C.m 移动到 privateA returns 错误 的评估 C 未定义。

另一方面,以下序列(大多数情况下都会出现)不会显示错误: 1') A.mC.m 目录, A.m 调用 B.mB.mprivate,这次调用C.m A 的评估工作正常。 3') 将 C.m 移动到 privateA 的评估仍然有效 fine.

因此,出于某种原因,步骤 2) 对错误的发生至关重要。

EDIT3:对于来自 GUI 的新鲜 Octave 这就是它对我的工作方式(在 Windows 10 Pro 20H2 上,也许这很重要):

>> cd C:\Octave\test\
>> ls
 Volume in drive C is Windows
 Volume Serial Number is XXXX-XXXX

 Directory of C:\Octave\test

[.]       [..]      A.m       C.m       [private]
               2 File(s)            101 bytes
               3 Dir(s)  129 967 509 504 bytes free
>> A
this is A
this is B
>> % now edit B to call C
>> A
this is A
this is B
this is C
>> movefile("C.m", "private/C.m")
ans = 1
>> A
this is A
this is B
error: 'C' undefined near line 3, column 3
error: called from
    B at line 3 column 3
    A at line 3 column 3

你的建议应该适用于 Octave,所以我相信你的错误在别处。你能提供一个最小的例子来说明它是如何不起作用的吗?这是我在 Octave 中的工作:

$ cat dd/A.m 
function A ()
  disp('this is A')
  B()
endfunction

$ cat dd/private/B.m 
function B ()
  disp('this is B')
  C()
endfunction

$ cat dd/private/C.m
function C ()
  disp('this is C')
endfunction

$ octave --path 'dd' --eval 'A()'
this is A
this is B
this is C