从 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。
我有几个函数想设为私有,比如 A 和 B。它们有一些共同的部分,所以很自然地分离出这部分并创建另一个函数,比如 C,从 A 的内部调用和 B.
我把C和A和B放在同一个私有目录下,它似乎该语言不允许这种构造,因为我收到一条错误消息,指出 C 未定义。我发现它违反直觉,尽管如此,根据 Octave 文档的上述引用,这是可以预期的,它说私有函数只能从 parent 目录中看到。
我尝试在第一个子目录中放置一个嵌套的私有子目录(相对路径为“private/private”)作为解决方法,但它没有解决问题,我仍然收到未定义 C.
的错误
因此,从私有 A 和 B 调用 C 的唯一方法似乎是是让它 public 可见,即使从代码架构的角度来看 C 不应该 public ,因为它仅由私有函数调用。另一种方法是在 A 和 B 中保留 C 相同代码的副本 - 使用违反DRY原则的所有不良后果。
编辑:正如评论中所指出的,这个问题似乎是 Octave 特有的。在 Matlab 中,您可以从其他私有函数访问私有函数。
我的问题是:在 Octave 中维护私有函数公共部分的正确方法是什么?
EDIT2:问题确实似乎是当前版本 Octave 中的一个 bug。 提供的 MWE 工作正常 除非...
我发现下面的序列是一个最小的-不是的工作示例,导致错误显式:
1)
A.m和C.m在目录,A.m 调用 B.m。
B.m 在 directory/private 中,最初 NOT 调用 C.m。
A 的评估工作正常。
2)
修改B.m调用C。
A 的评估仍然有效。
3)
将 C.m 移动到 private。
A returns 错误 的评估 C 未定义。
另一方面,以下序列(大多数情况下都会出现)不会显示错误:
1')
A.m 和 C.m 在 目录, A.m 调用 B.m。 B.m在private,这次调用C.m
A 的评估工作正常。
3')
将 C.m 移动到 private。
A 的评估仍然有效 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
在 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。
我有几个函数想设为私有,比如 A 和 B。它们有一些共同的部分,所以很自然地分离出这部分并创建另一个函数,比如 C,从 A 的内部调用和 B.
我把C和A和B放在同一个私有目录下,它似乎该语言不允许这种构造,因为我收到一条错误消息,指出 C 未定义。我发现它违反直觉,尽管如此,根据 Octave 文档的上述引用,这是可以预期的,它说私有函数只能从 parent 目录中看到。
我尝试在第一个子目录中放置一个嵌套的私有子目录(相对路径为“private/private”)作为解决方法,但它没有解决问题,我仍然收到未定义 C.
的错误因此,从私有 A 和 B 调用 C 的唯一方法似乎是是让它 public 可见,即使从代码架构的角度来看 C 不应该 public ,因为它仅由私有函数调用。另一种方法是在 A 和 B 中保留 C 相同代码的副本 - 使用违反DRY原则的所有不良后果。
编辑:正如评论中所指出的,这个问题似乎是 Octave 特有的。在 Matlab 中,您可以从其他私有函数访问私有函数。
我的问题是:在 Octave 中维护私有函数公共部分的正确方法是什么?
EDIT2:问题确实似乎是当前版本 Octave 中的一个 bug。
我发现下面的序列是一个最小的-不是的工作示例,导致错误显式: 1) A.m和C.m在目录,A.m 调用 B.m。 B.m 在 directory/private 中,最初 NOT 调用 C.m。 A 的评估工作正常。 2) 修改B.m调用C。 A 的评估仍然有效。 3) 将 C.m 移动到 private。 A returns 错误 的评估 C 未定义。
另一方面,以下序列(大多数情况下都会出现)不会显示错误: 1') A.m 和 C.m 在 目录, A.m 调用 B.m。 B.m在private,这次调用C.m A 的评估工作正常。 3') 将 C.m 移动到 private。 A 的评估仍然有效 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