【发布时间】:2021-07-23 20:32:52
【问题描述】:
在 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 的唯一方法似乎是使其公开可见,即使从代码架构观点 C 不应该是公共的,因为它只被私有函数调用。另一种方法是在 A 和 B 中保留相同的 C 代码副本 - 违反 DRY 的所有不良后果原则。
编辑:如 cmets 所示,这个问题似乎是 Octave 特有的。在 Matlab 中,您可以从其他私有函数访问私有函数。
我的问题是:在 Octave 中维护私有函数的公共部分的正确方法是什么?
EDIT2:问题确实似乎是当前版本的 Octave 中的一个 错误。 carandraug 提供的 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 返回错误,而 C 未定义。
另一方面,以下序列(在大多数情况下都会出现)并没有揭示错误: 1') A.m和C.m在目录中,A.m调用B.m。 B.m 处于private,这次调用 C.m A 的评估工作正常。 3') 将 C.m 移至 private。 A 的评估仍然正常。
因此,出于某种原因,第 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
【问题讨论】:
-
“但我希望在这两种语言的实现中都能实现兼容性”,这不是一般规则,仅供参考。
-
我同意,Matlab 和 Octave 不完全兼容,但知道这是否是兼容性问题对我来说也非常有用。
-
在 MATLAB 中,您可以从同一私有目录中的另一个私有函数调用私有函数。即使文档在这方面措辞不佳。
-
非常感谢!所以我的问题是八度,我会编辑它。
-
@PiotrM 是的,这证实了我的观点。这只是您在同一会话中更改函数定义的副作用。 Octave 不会重新编译它已经编译的文件,除非你明确要求它,例如使用
clear functions(或者您可以简单地重新启动您的八度会话)。这是一个功能,而不是一个错误。许多其他语言的工作方式相同(例如 python)。
标签: octave private code-organization