How to write a single Octave script with function definitions compatible with Matlab scripts?

喜夏-厌秋 提交于 2020-06-23 03:09:51

问题


If I write this:

clc
clear

close all
format long
fprintf( 1, 'Starting...\n' )

function results = do_thing()
    results = 1;
end

results = do_thing()

And run it with Octave, it works correctly:

Starting...
results =  1

But if I try to run it with Matlab 2017b, it throws this error:

Error: File: testfile.m Line: 13 Column: 1
Function definitions in a script must appear at the end of the file.
Move all statements after the "do_thing" function definition to before the first local function
definition.

Then, if I fix the error as follows:

clc
clear

close all
format long
fprintf( 1, 'Starting...\n' )

results = do_thing()

function results = do_thing()
    results = 1;
end

It works correctly on Matlab:

Starting...

results =

     1

But now, it stopped working with Octave:

Starting...
error: 'do_thing' undefined near line 8 column 11
error: called from
    testfile at line 8 column 9

This problem was explained on this question: Run octave script file containing a function definition

How to fix it without having to create a separate and exclusive file for the function do_thing()?

Is this issue fixed on some newer version of Matlab as 2019a?


回答1:


The answer is in the comments, but for the sake of clarity:

% in file `do_thing.m`
function results = do_thing()
    results = 1;
end

% in your script file
clc;   clear;   close all;   format long;
fprintf( 1, 'Starting...\n' );
results = do_thing();

Accompanying explanatory rant:

  • The canonical and safest way to define functions is to define them in their own file, and make this file accessible in octave / matlab's path.
  • Octave has supported 'dynamic' function definitions (i.e. in the context of a script or the command-line) since practically forever. However, for the purposes of compatibility, since matlab did not support this, most people did not use it, and quite sensibly relied on the canonical way instead.
  • Matlab has recently finally introduced dynamic function definitions too, but has opted to implement them explicitly in a way that breaks compatibility with octave, as you describe above. (rant: this may be a coincidence and an earnest design decision, but I do note that it also happens to go against prior matlab conventions regarding nested functions, which were allowed to be defined anywhere within their enclosing scope).
  • In a sense, nothing has changed. Matlab was incompatible with advanced octave functionality, and now that it has introduced its own implementation of this functionality, it is still incompatible. This is a blessing in disguise. Why? Because, if you want intercompatible code, you should rely on the canonical form and good programming practices instead of littering your scripts with dynamic functions, which is what you should be doing anyway.



回答2:


Octave's implementation of local functions in scripts is different from Matlab's. Octave requires that local functions in scripts be defined before their use. But Matlab requires that local functions in scripts all be defined at the end of the file.

So you can use local functions in scripts on both applications, but you can't write a script that will work on both. So just use functions if you want code that will work on both Matlab and Octave.

Examples:

Functions at end

disp('Hello world')
foo(42);

function foo(x)
  disp(x);
end

In Matlab R2019a:

>> myscript
Hello world
    42

In Octave 5.1.0:

octave:1> myscript
Hello world
error: 'foo' undefined near line 2 column 1
error: called from
    myscript at line 2 column 1

Functions before use

disp('Hello world')

function foo(x)
  disp(x);
end

foo(42);

In Matlab R2019a:

>> myscript
Error: File: myscript.m Line: 7 Column: 1
Function definitions in a script must appear at the end of the file.
Move all statements after the "foo" function definition to before the first local function definition. 

In Octave 5.1.0:

octave:2> myscript
Hello world
 42

How it works

Note that technically the functions here in Octave are not "local functions", but "command-line functions". Instead of defining a function that is local to the script, they define global functions that come into existence when the function statement is evaluated.



来源:https://stackoverflow.com/questions/55770635/how-to-write-a-single-octave-script-with-function-definitions-compatible-with-ma

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!