【问题标题】:octave 3 vs 4 script compatibility; where's REAL documentation of Executable-Octave-Programsoctave 3 vs 4 脚本兼容性; Executable-Octave-Programs 的真实文档在哪里
【发布时间】:2018-11-21 04:49:15
【问题描述】:

第 1 部分:在 octave 3.4.3(在 centos 6.6 上)跟随脚本文件“joe.m”(但对于 3.x minus --no-gui):

#!/bin/bash
# for-bash:
#{
  exec octave -q --no-gui --no-init-file "$0" ${1+"$@"}
#}
# for-octave:
function jim ()
  printf ("program_name: '%s'\n", program_name ());
endfunction
printf ("calling jim\n")
jim

产生输出:

calling jim
program_name: 'joe.m'

但在 octave 4.2.1 中,它会发出警告,并显示为自动调用(!?) jim,并且不运行顶级立即代码(!?),没有输出行“调用 jim”:

warning: function name 'jim' does not agree with function filename '/tmp/joe.m'
program_name: 'joe.m'

第 2 部分:如果我将同一文件重命名为“jim.m”,那么在 octave 3.4.4 中,输出为:

calling jim
program_name: 'jim.m'

在 octave 4.2.1 现在可以避免警告,但仍然缺少“调用 jim”行。

第 3 部分:定义零函数后,顶级代码在两个版本中执行。

在哪里记录或控制这些行为(以及从版本 3 到 4 的行为变化)?没有提到类似的东西:

https://octave.org/doc/v4.2.1/Command-Line-Options.html

https://octave.org/doc/v4.2.1/Executable-Octave-Programs.html

如何编写兼容 3.x 和 4.x 版本的 octave 文件,或者如何使用额外选项调用 4.x 以与 3.x 兼容?即使定义了函数,如何在 4.x 中执行顶级代码?

在没有相同文档的情况下,如何确定性地知道(无需反复试验)在 4.x 中将自动调用什么函数(以及使用什么参数)?这个例子不足以确定它,因为只有一个函数:如果有多个函数(joe 和 jim),那么顺序是否重要,相对于是否匹配文件名?

编辑:我包含 shebang(独立脚本)以试图不“提出错误的问题”或过早地将问题优化为我自己的“尝试的解决方案”,但无论有没有它,行为都是相同的。我需要脚本:不使用八度音程的绝对路径,并接受额外的单独选项(我无法在 4.2.1 中将 --no-gui 合并到 -qf 中)。欢迎您的简化。

【问题讨论】:

  • 如果shebang行与问题无关,请将其删除。我花了一段时间来解析它。让人们专注于重要的事情。请参阅minimal reproducible example(尤其是 minimal 部分!)。
  • 谢谢。我做了一个编辑来解释。也许我最好把 shebang 拆分成一个后记。

标签: octave


【解决方案1】:

有不同的 .m 文件类型,包括(根据 Octave 4.2.1):

  1. Function 文件: 包含一个或多个函数定义的文件。函数文件的名称通常与文件中定义的第一个函数的名称匹配。
  2. Script 文件: 包含代码行的文件,包括函数定义。

    与函数文件不同,脚本文件不能以关键字 function 开头。如果是这样,Octave 将假定它是一个函数文件,并且它定义了一个函数,一旦定义就应该对其进行评估。

  3. 类定义文件。

Octave 执行时的行为如下:

$octave File

记录在 Octave 的一个源文件 (oct-parse.yy) 中:

执行脚本文件的内容。为了与 Matlab 兼容,还可以通过调用它定义的不带参数且 nargout = 0 的函数来执行函数文件。

这里因为你的文件以关键字function开头,所以它被认为是一个函数文件,所以无论你是否调用jim,都会自动调用函数jim。因此,您可以从文件末尾删除表达式jim,并看到该函数被自动调用。在 3.4.3 版本中,我认为它被假定为脚本文件。

要解决这个问题,你需要在文件的开头添加一个表达式,而不是function关键字,以将其转换为脚本文件:

#!/bin/bash
# for-bash:
#{
  exec octave -q --no-init-file "$0" ${1+"$@"}
#}
# for-octave:
1;
function jim ()
  printf ("program_name: '%s'\n", program_name ());
endfunction
printf ("calling jim\n")
jim

【讨论】:

  • 帮助很大。 3.x 和 4.x 兼容性仍未解决。我得到了免费的警告(4.x 似乎是一个警告的雷区),函数名与文件名匹配时会发出警告(脚本文件),而当它们不匹配时会发出警告(函数文件)。
  • 如果您想禁用警告,您可以在startup file 中输入以下命令:warning( 'off','Octave:function-name-clash')。您可以找到所有警告的here 列表。我认为 3.x 的行为是一个错误,稍后会修复。如果您需要 3.x,您可以同时安装 4.x 和 3.x 并使用您想要的。
  • 当脚本文件具有同名功能时,我发现禁用警告的唯一方法是warning( 'off','all');,如果使用-qf,则无法及时执行此操作。强制我从 octave 3 重命名函数(或脚本文件)以在 octave 4 中使用它们。
猜你喜欢
  • 2016-04-30
  • 2016-08-18
  • 2020-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-10
  • 1970-01-01
相关资源
最近更新 更多