Octave 运行包含八度本地函数的简单脚本时出错

Octave 运行包含八度本地函数的简单脚本时出错,octave,Octave,我的文件testtest.m看起来像: pluse(1, 2) function retval = pluse(input1, input2) retval = input1 + input2; endfunction 然后我得到: error: 'pluse' undefined near line 1 column 1 error: called from testtest at line 1 column 1 为什么会出现这个错误 要正确回答你的问题,我需要指出两件事: 在oc

我的文件testtest.m看起来像:

pluse(1, 2)
function retval = pluse(input1, input2)
retval = input1 + input2;
endfunction
然后我得到:

error: 'pluse' undefined near line 1 column 1
error: called from
    testtest at line 1 column 1

为什么会出现这个错误

要正确回答你的问题,我需要指出两件事:

  • 在octave和matlab中创建函数的标准方法是将其放置在一个同名的专用文件中,并以函数声明开始该文件。由此推论,路径中以函数声明开头的任何文件在启动时都会被检测到,并作为可调用函数提供给用户

  • Octave多年来一直支持“运行中”函数定义(事实上也支持后续将此类“运行中”函数“导出”到文件);matlab最近才加入了“动态”功能(我想是2016b吧?),并选择了与倍频程稍有不同的实现方式(大概是为了保持倍频程?:p)

  • Octave的实现直接遵循语言规则。任何以非“函数声明”语句开头的文件都被视为脚本,即独立语句序列。因此,在脚本的开头出现了无害的
    1
    ,这是一个非常简单的“非函数声明”语句,但实际上它可以是任何东西。然后,脚本可以根据需要具有任意多个“正在运行”的函数定义。对于要在“正在运行”上下文中使用函数的语句,显然需要先定义函数。这源于一个基本原则,即脚本与函数不同,它有效地表示一个简单的语句集合,这些语句按顺序运行,无需任何预处理,并且可以简单地将这些命令复制/粘贴到它们的终端或从终端粘贴这些命令,并期望它们运行

    Matlab最近的实现有效地打破了这种功能/范式。要了解我的意思,请将上面的代码复制粘贴到一个新的终端(或高亮显示,然后按F9),然后看着它断开。脚本不再是可复制/粘贴的,但假定matlab将先读取并加载任何函数定义,然后返回并尝试运行其余命令;换句话说,matlab现在对待脚本就像对待函数一样。请注意,matlab仍然需要一个脚本以非函数声明语句开头,因此实际上,该位与需要以“1”开头的倍频程相同。唯一改变的是这种预先加载“即时”函数的前瞻行为,我认为这在脚本上下文中不一定是一件好事

    我认为Octave的方法更有意义,尽管在(无意中)将脚本视为有效的非脚本时,您使用matlab指出了它的便利性。哪一个可能一开始就不应该这样做。如果您需要前瞻功能和嵌套,那么首先确实应该编写适当的函数并提供相关的作用域上下文。

    。但由于没有明确的示例,我将其发布在这里,以便其他人可以找到一个针对倍频程和MATLAB的明确运行示例

    % works in Octave %%%
    % sth. must be *before* a (local) function is declared
    1; % or "2;" or "1+1;" or whatever
    
    % local function must be declared *before* it is run in Octave
    function retval = pluse(input1, input2)
      retval = input1 + input2;
    end % or "endfunction"
    
    % Now you can use the local function
    pluse(1, 2)
    
    由于MATLAB示例不在倍频程中运行,因此倍频程与MATLAB之间存在不兼容性,反之亦然:

    % works in MATLAB %%%
    % You can use the local function
    pluse(1, 2)
    
    % local function must be declared at the end of file for MATLAB
    function retval = pluse(input1, input2)
      retval = input1 + input2;
    end
    

    由于这种不兼容性,问题是是否应该真正使用本地函数。Octave和MATLAB都适用的解决方案是在另一个文件中使用“普通”函数…

    您的文件应该有一个名称“pluse.m”,谢谢您的回答,但这样做会导致错误“在索引表达式中无效使用script~/Octave/pluse.m”。我真的不知道为什么这不起作用,因为我想这是八度音阶的一个基本特征。(我使用Octave 4.0.0,有问题吗?)这是基本的matlab/Octave语法。a) 函数通常在它们自己的文件中定义,b)如果要当场定义函数,则需要先定义它,然后才能使用它c)脚本文件不能以“function”语句开头,因为这是为函数文件保留的。特别是,谢谢你,塔索斯。因此它不同于MATLAB,在MATLAB中可以运行上面的代码。在八度音阶中,你需要做:[[[1;函数retval=pluse(input1,input2)retval=input1+input2;endfunction pluse(1,2)]],我想这有点尴尬。嗨,马丁。回复时请使用“标记”(例如@tasospapstyllanou),否则我不会收到通知(而线程的所有者,即您,会自动收到新评论的通知,无论它们是否标记)。我不认为这对matlab有什么不同;也许是最新的版本。旧版本甚至不支持像这样的“现场”函数定义,而octave已经支持它们很多年了,所以也许matlab最近的实现允许这样做是偶然的(或者故意弄乱octave,哈哈)。但我不认为应该,让我在工作中检查一下……我已经在Octave问题跟踪器上发布了一个功能请求,并将其作为MathWorks支持部门的Matlab功能请求提交。也许有一天我们会看到统一。我认为Matlab的方法至少是一致的:Matlab的函数定义范例是声明性的,而不是程序性的。与某些动态语言不同,函数在执行
    function
    语句时不会突然出现。它们总是存在的,因为它们存在于文件系统的某个地方,或者在classdef或函数定义文件中(或者作为函数中的嵌套函数)。这很好,因为你不必担心它们何时被定义。但是,您不能在脚本的使用点附近定义脚本局部函数,这是一个令人遗憾的问题。这里还有另一个想法:也许Matlab要求局部函数位于脚本的末尾,以将它们与嵌套函数区分开来,嵌套函数是捕获包含函数中变量引用的闭包