0

I write some program at Matlab. I do it in .m file. And it's 300+ strings of code now, so it became not very comfortable for reading. My idea is to use it like in C++: I want to create local functions at the end of this file and put pieces of code into them. It would be easy to read and it would consist of some logical parts.

But I faced the fact that local functions can be created only in body of other function! So I can't create this:

x = 1;
y = 2;
z = myLocalFnc(x,y);

function res = myLocalFnc (a,b)
 res = a.*b;
end

This generate error:

Function definitions are not permitted in this context.

I can do it by including the whole code into one function:

function myBigFcn
x = 1;
y = 2;
z = myLocalFnc(x,y);
end

function res = myLocalFnc (a,b)
 res = a.*b;
end

But now all the variables became local and it return to workspace nothing. Modify input/output for this function any time I create some variable - I don't think I walk the right way... Here are described advantages and disadvantages of this method.

I know I can create function in additional .m file, save it and use in my script - OK, but a lot of them are single-operation, I don't want to create so much new files.

My question is ARE any other methods of code organizing?

Community
  • 1
  • 1
Mikhail_Sam
  • 10,602
  • 11
  • 66
  • 102
  • @excaza I guess my only reason for *not* flagging as a dupe is that we now have an *actual* solution in 2016b and that should be noted. – Suever Jul 11 '16 at 13:20
  • @Suever so add it as an answer to the dupe. There's no reason to have answered this in the first place... – sco1 Jul 11 '16 at 13:23

2 Answers2

2

If you really want your main thing to be a script (I don't recommend this), you can put all the other functions in separate .m files and call those from within the script.

The other option, as you've noted is to put the entire contents of your "main" part into a function at the top of your code. You can return all the necessary values via the output arguments or save them to a .mat file if you need access to them later.

As a side note, the ability to put local functions within a script (what you're trying to do) is present in R2016b which will be released later this Fall.

Update

If you want an easy way to convert your code to a function. You can easily save all variables to a struct at the end of your function automatically and just return this struct.

function output = my_script_that_is_now_a_function(inputs)

    % Do stuff

    % Now save all variables in a struct and return it
    tmpfile = tempname;
    save(tmpfile);
    output = load(tmpfile);
    delete(tmpfile);
end
Suever
  • 64,497
  • 14
  • 82
  • 101
  • Thank you for so fast response! Can you please add the information why you recommend to avoid using script? And what is better to use instead - .m file function? – Mikhail_Sam Jul 11 '16 at 12:46
  • 1
    @Mikhail_Sam Relying on a script to save all variables to the global workspace is generally a bad idea. What if you save a variable `M` and you already had a variable `M` there? You should use functions and explicitly return the variables you need and allow the user to specify where to store these variables – Suever Jul 11 '16 at 12:47
  • I get it. Looks like R2016b is what I want. I also understood about disadvantages of using script, but I like it at the stage of contraction my code - because I usually check a LOT of temporary variables, so adding all of them to function output - it's a lot of routine... – Mikhail_Sam Jul 11 '16 at 13:06
  • @Mikhail_Sam R2016b won't be available to the general public until the Fall. Why not save all of your variables to a struct at the bottom of your function. I'll add an example at the end of my post. – Suever Jul 11 '16 at 13:21
  • @Suever Do you really recommend the thing you posted as update? Looks like a very ugly hack to me... It can't be such a huge deal to think about the values one wants to return from a function, and return only those. – hbaderts Jul 11 '16 at 13:38
  • 1
    @hbaderts No I don't recommend it at all. The proper solution is to refactor the code. – Suever Jul 11 '16 at 13:38
1

One option, if you don't mind saving a file locally, is to restructure your code into multiple functions (all in the same file) and pass the necessary variables as output. You then have a short script which calls this function and creates the necessary variables.

For example, say your script looks like this

numPoints = 5;
a = randn(numPoints);
b = sin(a);
c = a + b;

You could restructure it to look like

function data = main()
  data.numPoints = 5;
  data.a = getA(data.numPoints);
  data.b = getB(data.a);
  data.c = getC(data.a, data.b);

function a = getA(numPoints)
  a = randn(numPoints);

function b = getB(a)
  b = sin(a);

function c = getC(a, b)
  c = a + b;

and create a script file which looks like

data = main();

You then have a struct called data which contains all of your variables. If you really want them to be contained in separate variables (i.e. not in a struct) then there are a couple of ways to do it. One is to unpack them manually,

a = data.a;
b = data.b;
c = data.c;

clear data;

Another is to save the struct, and then reload it (this has the advantage of keeping a copy of the workspace that you used for this fun of the function, for later analysis).

save('workspace.mat', '-struct', 'data');
load('workspace.mat');
Chris Taylor
  • 46,912
  • 15
  • 110
  • 154