Doug's MATLAB Video Tutorials

Top 10 MATLAB code practices that make me cry 64

Posted by Doug Hull,

I was chatting with the Application Support Engineers here at MathWorks about what kind of coding practices cause avoidable pain for MATLAB users.

Without further ado: The top ten and quick ways to not do them:

10.) Not using left hand zeros

Certain things must be learned the hard way. I learned this one bleary eyed evening as an undergraduate. Well into the night working on a MATLAB homework assignment that would “take ten minutes, fifteen if you type slow.” (yes, Dr. P, 13 years later I still remember that one! -smile-)

It is really easy to mistake a .5 for a 5. That is why I always use a left hand zero like 0.5.

9.) Plotting enormous amounts of data

My computer monitor has 2.3 million pixels, total. If I try to plot datasets with huge amounts of data in them, they will very often just look like a blob and slow the machine down in the process.

There is very often a better visualization available. Here is an example of changing the visualization to make it clearer and less taxing on memory.

8.) GUIs with garish color schemes

In an effort to emphasize certain buttons on their GUI, people will change the colors of them. Very quickly they end up with several different colored buttons, a non-standard background color, extra big buttons, etc…

Sticking with the default colors is a good move. Most professionally produced software sticks with the defaults, it ends up looking better.

7.) Using ans, or any other MATLAB function as a variable name or function.

When you do this, MATLAB will call whichever one is higher on the path. Some strange behavior can occur when you redefine a function like that. Unfortunately, MATLAB does not catch you doing this for the most part.

I try to avoid using variables and function names that are common terms like, mean, filter, etc… If there is any doubt, use the which command to find out if a function exists of a given name.

6.) Not using white space to good effect in code.

Even though you can put several commands on one line if separated by a semicolon, these lines can often be hard to notice. Not putting blank lines between sections of code can also make it harder to read.

White space is free, use it to make your code look good.

5.) Bad variable names

Variable names are often the only commenting that gets added to people’s code. Meaningful variable names are a great opportunity to make the meaning of your code more clear and to some degree, self-documenting.

Avoid using variable names like temp, aaa, r247899921. These just do not convey as much information to people that have to read your code as flagPassedInspection, centroidX, fidCurrentFile.

4.) Hard coding data into the MATLAB code file

Some people like to put some of their variables directly into the MATLAB code. That makes sense for small variables (I will let you define what small means for you). For instance, I would feel fine putting a 3×3 matrix into my code. I would think twice about a 10×10, and I would start using one of our file readers for a 100 x 100.

The worst instance I ever saw of this was some MATLAB code where the .M file was 4 GIG (not a mistake) long. All but a small amount of that was data written out in ASCII. This makes your code hard to read, maintain and understand.

3.) Exceptionally long files

Even if not hard coding data into a MATLAB code file, it is easy to just add on “just a few more lines of code” until you have thousands of lines of code in a single script. This makes your code hard to understand.

I try to use the rule that I should be able to see an entire script or function in one screen. This is not entirely practical, so I will at least break the code into logical sections that do fit on screen all at once.

2.) Globals

I have never seen MATLAB code where globals were the right thing to do. Exception: functions TIC and TOC use them quite nicely. Most of the time I have seen globals being used it was a situation where the code author did not understand scoping of variables. Rather than pass variables from one function to another, they were just being made global.

Why are people cautioned against using global variables? I will leave that to the consensus on Wikipedia.

1.) Eval

EVAL is right up there with globals. MATLAB user will often string together MATLAB commands to get sequential variable names s1, s2, s3… only to then have to use another EVAL statement to work with the sequential variable names! Very often, a cell array indexed with s{1}, s{2}, s{3}… would work much better.

I will also find that people use EVAL to get at certain fields in a structure (for example data.alpha) when they do not know at the time of writing the code what field they will want. Now the “.parens” notation makes that easier.

The other most common place to see people use EVAL when it is not needed is when they are trying to load a file or some other function like that. Very often they are trying to EVAL a string like “load filename.mat” not realizing that there is a functionsl form where you can use fileNameString = ‘filename.mat'; load(fileNameString)

64 CommentsOldest to Newest

Given some of your previous writings, I am surprised that you left out premature and/or unnecessary optimization. You know, where a person spends 3 hours to vectorize a code that is intended to only run once or twice at 2 seconds per shot. Number 11?

@Matt,

There was that and eight others that did not make the list. Premature optimization is often indistinguishable from just hard to read code! I don’t always recognize it as an optimization! :)

I was hoping to hear from people to see what theirs were. Top 19 did just not have the same ring to it! I guess if I think of one more, I can have the “top ten that make me cringe (instead of cry)” :)

6. Whitespace – YES! So much code I see seems to be from when a blank line meant a blank (wasted) card, spaces in the line meant your code took more cards to print, and more cards were a burden to carry and keep ordered. For a younger generation, it seems to be from when you only had 80×25 character screens, and whitespace meant you couldn’t see much code at once. Let go of the old habits because you don’t have those constraints. Let your code breathe, and be amazed at how many errors you can spot now.

5. Bad variable names – I often see bad variable names with copious accompanying comments that are having to explain what each variable’s purpose is.

One common thread to many of these things is feature discovery. It’s natural that you start to learn a new language’s basic parts. With that small kernel you can usually cobble together anything you need to do, given enough time and dwelling on doing it rather than taking a time to see if there’s another way to do it, knowing it will save you time over-and-over later rather than now.

MATLAB’s active M-Lint in the editor helps with some discovery. Good examples and cross-referencing in the documentation also help.

Great Topic:
My personal peeves:
1) People who ignore mlint messages. Repeat after me : mlint is your friend, mlint is your friend.

2) Untidy code and crummy variable names: a simple ctrl-A, ctrl-I will clean up 99% of the code that gets messy as you edit. And for the love of all that is holy do not give me variable names that start with ‘my’ anything.

3) Hard coding just about any non-trivial data (and some seemingly trivial) in the code will bite you down the line.

Using i in a loop is fine to me. I would say the opposite: always use the notation “1+1i” when writing complex numbers.

i disagree with not using globals. Global variables are very practical when you have large data sets that are being modified within a function. The moment you change a variable inside a function, matlab makes a copy which implies using a lot more memory. that’s a big problem when you have 800MB sized variables! In such cases, global is extremely convenient – preallocate and update the same one all the time using logical indexing. Far more memory efficient, wouldn’t you agree?

@Jayveer,

That is an excellent point. That is one of the good uses of globals. I have heard of people using them that way, but I have never seen it!

I think it is one of those situations where 99% of all global variables give the other 1% a bad name!

Doug

Just an fyi…

Rather then use globals I created a handle class with dynamic properties.

This way you can pass the class around of big variables.

classdef dynoclss < dynamicprops

end

Then you can do this:

x = dynoclss;
x.addprop(‘foo’)
x.foo=rand(1e7,1);

pass x to your functions and go crazy.

Stephen

I needed to store the arrival times of wavefronts and I used variable (2D array) with the name “times”. Well, in Matlab “times” is the name of a function for multiplication… I accidentally figured out the mistake

@Stephen

Nice!

@Petros

The reason all (except global) are on here is because I made ALL of these mistakes in the past. Experience is a great teacher!

Doug

@Stephen
Very Nice! In the pre classdef days one trick I used was storing large common data in the root’s appdata.
bigData = rand(1e7,1);
setappdata(0,’CommonData’,bigData);

then when you need it
bigData = getappdata(0,’CommonData’);

Had to build some framework for managing it but all in all worked pretty well.

Matt

Matt Whitaker is correct. When a code module is complete, the M-Lint should be silent.

@Doug,

Many of these items are already covered in some of the various MatLab coding style guides. Maybe you could reference your favorite ones.

Nice list. I would add two items which are practices of omission, i.e., not doing the right thing.

11. Not validating function arguments and return values.

12. Inadequate comments, especially if the variable names are not descriptive (#5).

For example (without my comments),

t1F = @(b,a) b+a;
t2F = @(b,a) asin(N1/N2*sin(t1F(b,a)));
t3F = @(b,a) t2F(b,a)-a;
t4F = @(b,a) asin(N2/N3*sin(t3F(b,a)));
y1F = @(x,y,b,a) y(1);
y2F = @(x,y,b,a) y1F(x,y,b,a) + (x(2)-x(1))*tan(b);
y3F = @(x,y,b,a) y2F(x,y,b,a) + (x(3)-x(2))*tan(t3F(b,a));
y4F = @(x,y,b,a) y3F(x,y,b,a) + (x(4)-x(3))*tan(t4F(b,a));

It was obvious what the function y4F did when I wrote this 3 years ago and isn’t too hard to figure out now. But why figure it out again? Perhaps nested anonymous function calls should be added to the list.

Also to two of eval’s cousins, str2num and feval, can be very useful and safe. I frequently use str2num, which of course calls eval in a try-catch block, to allow a user to enter parameters such as plot scaling factors as a expressions. Why make someone pull out a calculator when there’s a great big one (MATLAB) behind that GUI you wrote for them?

Ken

@Ken,

Nested anonymous functions aren’t a bad coding practice … as long as it’s clear why you’ve nested them and what each contributes. In your case, I would argue the problem occurs not in the nesting of the functions but in the names of the variables in which you store them.

Therefore I’d expand item 5 on the list — it’s not just bad _variable names_ that can cause problems, but bad _identifiers_, which includes things like variable names, function names, struct array field names, and even MAT-file (or other data file) names.

Will you remember what’s stored in mat123.mat six months from now?

How about what’s stored in financialDataQ1Y2010.mat?

Hi,

I don’t like the use of some relatively new features of Matlab:

1. The use of anonymous functions, see the list of Ken Gerrard for some horribly unreadable examples.

2. The use of nested functions, they are confusing regarding variable scope.

3. The use of functions like bsxfun without very detailed comments describing what happens. Too bad that the far better understandable for-loops are still soooo slow in Matlab…

Markus

There is also a use of classes for avoiding global constants: Use constant properties of classes. They are initialized at first time use of the class, so you can make them dependent on a config file, elaborate one time calculations etc. You can group the constants by meaningful class names, use the meta information in the class for validation purposes etc.

I like this post,

Why don’t you open a wiki page dedicated to MATLAB, I guess the mathworks will find interesting things in there.

I agree with most of the things you wrote,

These are the things that cause a lot of pain to me:

- lack of MACROS, why not include #define operator like in c++ ?

- huge overhead time in function calls, especially nested ones.

- I would like to pass arrays to function as reference.

- globals: why not leaving a dedicated space in the header for globals? wouldn’t that be easier?

- can not build an arrays of structure, only structure of arrays. If you know how to do it please tell me.

- the rotate command in figures is not arc-balled! it only rotates on the centroid. You can spend most of your time rotating the figure like a dog trying to bite his tail, no way to focus what you want to see.

- there is no built-in library for data structure like stl containers. This can be very painful when you need it.

- HELP MEMORY ERROR: in my opinion it occurs for too small arrays.

If I remember something else I will add it later

Luigi

Regarding #7, the reuse of MATLAB-defined identifiers, the chief problem with this is that you can’t know what functions are defined by MATLAB. I may be working with bare MATLAB at one computer, while another computer may have Simulink and a whole slew of additional toolboxes. From the bare installation, I have no way to know what other functions are floating around out there without checking the website. Fortunately, MATLAB’s name resolution rules work in the programmer’s favor such that mystery functions you’ve never heard of in super-awesome-toolbox usually do not cause problems.

I’ve also had the misfortune of needing this behavior to suppress calls to “keyboard” in code I inherited for testing. Add that to the list of things that will make you cry — using keyboard() instead of assert() or error(). That really messes things up when trying to write automated tests.

The converse of #7 is that it is difficult to figure out what toolboxes a piece of code actually uses.

One of my personal annoyances is to see an m-file script with the following at the top:

close all; clear all;

This is especially bad when you send your code to other people, who may not realize that your script will wipe out anything they may currently be working on.

- Ben

I hate when people hard code inputs that are meant to be changed each time, especially file names! Why not just use inputdlg or input functions? They’re just as fast to code, especially if you’re not doing any error checking on the hard-coded file name anyway. I even see times where multiple lines contain the different file names and commenting and uncommenting occurs.

Quite often, the person goes through the trouble of using Windows Explorer to find the file name, copy it, and paste it, save the file, then run the script. At that point, just use uigetfile and be done with it!

@Luigi

My impression is that you try to code Matlab with C++ techniques.

- lack of MACROS, why not include #define operator like in c++ ?
>> You do not need it in Matlab (also not in Python, not in Ruby, not in Java, not in C#).

- huge overhead time in function calls, especially nested ones.
>> Agree! That’s the cost of using a dynamically typed interpreted language, do not ever try to compare it to C++. But Matlab and C++ have completely different purposes. And with all ultra-efficient build-in Matlab functions your Matlab code programmed properly can be made very fast.

- I would like to pass arrays to function as reference.
>> Just do it.
http://blogs.mathworks.com/loren/2007/03/22/in-place-operations-on-data/
http://blogs.mathworks.com/loren/2006/05/10/memory-management-for-functions-and-variables/

- globals: why not leaving a dedicated space in the header for globals? wouldn’t that be easier?
>> I think this is a very minor point.

- can not build an arrays of structure, only structure of arrays. If you know how to do it please tell me.
>> What do you want???

- the rotate command in figures is not arc-balled! it only rotates on the centroid. You can spend most of your time rotating the figure like a dog trying to bite his tail, no way to focus what you want to see.
>> You are probably right.

- there is no built-in library for data structure like stl containers. This can be very painful when you need it.
>> Why? You do not need it in Matlab. Newer Matlab Versions have even Hash tables.

- HELP MEMORY ERROR: in my opinion it occurs for too small arrays.
>> It is also about memory fragmentation.

Fun list. My pet peeves are:
-Hyper-dense lines of code. My coworker likes to do this, packing fifteen different function calls into one line. I’m impressed, OK, but I can’t read it.
-Haphazard indentation. As mentioned above it’s so easy to do this right.
-Repeating giant chunks of code, but changing one little thing. It’s called a “for” loop — use it!

“One of my personal annoyances is to see an m-file script with the following at the top:


close all; clear all;

This is especially bad when you send your code to other people, who may not realize that your script will wipe out anything they may currently be working on.”

Very true if you are not expecting the commands. Unless your script is supposed to be working on the problem that is contained in the (assumed base) workspace, I think that all scripts aimed at answering a particular question should start with at least the “clear” command. So many errors can occur when there is some dependency on workspace contents (whether by design or not) for a script to run correctly. Starting from scratch ensures repeatable results wherever the code is run.

My pet peeve is try/catch blocks used for normal control flow. For example, testing whether a struct has a certain field by trying to dereference it and catching the “no such field” error instead of first using a non-erroring test like isfield(). Bad in any language with exceptions, but particularly bad for Matlab because “dbstop if all error” is so useful, and try/catch in the normal control flow will hobble it by triggering spurious error breakpoints.

Regarding #7: I agree with Arthur, it is difficult to assure not overriding MATLAB functions (I don’t really like typing “which” all the time, when coding). That is why I usually put all my code in its own namespace, e.g. work.myfun(..) or for the lazy guys: w.myfun(), so I am at least save in using the function names I like. The additional typing is not an issue to me, thanks to TAB completition.

Wow, you all had a lot to say while I was on vacation!

Some of this does come down to “religious issues”. I personally advocate putting

clear
close all
clc

at the top of every script because I want things reproducible. I am never worried about clearing out the workspace since everything I do is in a script or function, so I should be able to get back to that point easily.

I’m gree with Doug on #33!

and overall I find very important that things must be reproducible.

Another point is the difference between ‘clear all’ and his good cousin ‘clear’, because the first one clear also the breakpoints on ALL the functions and scripts you have opened on the M-Editor.

but I disagree with ‘clc’, because with it you clear past error messages, there is enough memory for this.

@J.R.

It is funny, I use clc specifically because I want to clear the old error messages. I am running the code for a second time specifically to see if my changes fixed the errors. I would not want to confuse myself by thinking that the old error message corresponds to the new code!

Doug

Re eval: How would you treat conversion w/o eval?

For instance:

c=class(a);

a=double(a);% to perform some arithmetic on a
do something to a

a=eval([c ‘(a);’]);

–P

@P

I did not know, but Loren did!

>> a = uint8(1)

a =

    1

>> className = class(a)

className =

uint8

>> a = double(a)

a =

     1

>> a = cast(a,className)

a =

    1

I mostly agree with Doug’s list, although there are a few exceptions. One that comes to mind is hard-coding the Gauss points and weights into an M-File for integration. I have seen this done and it made sense to do it.
Here are some of my pet peeves.

- clear all,clc at the start of a function M-File. I do sometimes use HOME instead of CLC.
– Use of i or j as a loop index. I always (and only) use double letters as a loop index. For example, ii or jj or kk. That way there is no overwriting of built-ins, and these variables always are known as a loop index.
– Many blank spaces between lines in a M-File.
– Massive IF-ELSEIF chains instead of a SWITCH.
– Not pre-allocating arrays which then grow in a loop.
– Recursion. I know, it has it’s place, I just can’t bring myself to like it.
– No help in a function M-File
– Dumping intermediate results to the command window. I see this one often.
– Programming as if we have infinite precision. Yikes!

@Matt,

I like the idea of HOME instead of CLC. I will have to try that for a while.

ii, jj, kk. That is a nice little convention. Mush like I use vi (Valid Indices) as the output from a find operation. I always know what means. After many goofed up indices with i in a loop, out of frustration, I made up GAPLI (Generic All Purpose Looping Index)

I wish I understood recursion better, it often confuses me!

I might have to make up a follow up post to this one “ten more MATLAB coding practices that make blog commenters cry!”

Thanks!
Doug

@Matt, @Doug, and @J.R.,

Regarding ‘close all’ and ‘clear all’ at the top of scripts, it sounds like Matt (comment #38) has the same coding practice as I do. In order to make things reproducible I almost always write functions instead of m-file scripts. This way I always know exactly what I’m passing in and what I’m passing out, and I know that the function is starting from a clean workspace of it’s own (and I refuse to use ‘global’ variables). While I’m writing/debugging I may put a “keyboard” as the last line of code, so I can see what’s happening before that workspace gets cleared. Once I’m satisfied the function works as desired, I just remove the “keyboard” line.

My big reason for *not* wanting “clear all” is that I keep the data I’m working with in structs in the workspace. The data sets tend to be rather large and take a non-negligible amount of time to load from the .mat file I store them in (at least 10-30 seconds to load, if not longer). If the meat of the function only takes 1-2 seconds, it’s a lot of overhead to clear the struct then reload it again every time.

- Ben

I am very much in agreement with Ben. I work almost exclusively in functions instead of scripts, and often have scratch data in my workspace or extensive state in my open figures. Running a script that has “close all; clear all” at the beginning (or, even worse, buried inside it) nukes all of this state without warning.

-Ross

Put me in the “no clear or close all” camp. I usually have lots of figures open and things in the base workspace and scripts that clear those without warning are no fun.

When I start coding something new, I usually test some things at the command line first. If that works out, I put it into a .m function file and continue working. I usually put a debugger breakpoint at the last line so I can inspect the results, and if I want to, I dump relevant variables to the base workspace using assignin(‘base’,….).

I reuse the figure numbers each time I run the script. (I usually turn off most figure creation when things look right, but keep a switch so I can use them for diagnostics.) I created a “number increment function”, next_function, for this purpose, that works in the following way:

next = next_function(10); % generate the increment function next, that will start at 10
figure(next()); clf; % creates and clears figure(10)
plot stuff
figure(next()); clf; % creates and clears figure(11)
plot more stuff
etc.

In that way, I can easily put new figures in between others, and still keep the figure numbers in order following the order they appear in the code.

I just wanted to mention that I totally agree with Luigi regarding the problem with the 3D rotate command.

Another problem for me is that the elevation angle rotation is constrained to (-90 90]. I don’t see any reason for this – the azimuth angle is not limited in this way, so why limit the elevation? Also, I can not reach elevation = -90; -88 works, -89 works, but when I reach what should be -90, the plot snaps back to +90, which can be pretty frustrating.

I’m stuck with 2007a, so maybe these have been addressed recently, I wouldn’t know.

Luigi asked:
“- can not build an arrays of structure, only structure of arrays. If you know how to do it please tell me.”

It’s easy to build either a structure whose fields are arrays:

b = struct('Name', 'Steve', 'BowlingScores', [90 103 86 117]);

or to build an array of structures. Two ways to do so:

s1(1) = struct('Name', 'Steve L', 'Blogger', false);
s1(2) = struct('Name', 'Loren', 'Blogger', true);
s1(3) = struct('Name', 'Doug', 'Blogger', true);
s2 = struct('Name', {'Steve L', 'Loren', 'Doug'}, 'Blogger', {false true true});
isequal(s1, s2) % returns true

Note that while I’ve used STRUCT to construct these struct arrays, you can do so using normal subscripting.

s3.Name = 'Steve L'; s3.Blogger = false;
s3(2).Name = 'Loren'; s3(2).Blogger = true;
s3(3).Name = 'Doug'; s3(3).Blogger = true;
isequal(s1, s3) % also returns true

Hello Doug,
Regarding not using global variables. What is your opinion about using global variables to prevent this type of thing:

function a=myFunction(b,c,d,physicalParameters)
mass=physicalParameters{1};
density=physicalParameters{2};
speed=physicalParameters{3};
kernel=physicalParameters{4};
....

I don’t like REDEFINING the mass and the density and all that because it takes up so much extra space. Is it dangerous to have mass and density and all those as global variables ?

@Juliette,

Are these huge variables? Are you running out of memory? I doubt they are. Making them global is not a recommended practice, it can cause debugging problems later and takes away on of the reasons for using functions- scoping of variables.

Doug

I use globals for debugging and plotting switches. Usually, I’ll have one called ‘debugYN’ and one called ‘plotYN’. By changing these booleans at the global level, I can change is my programs will or will not plot, or deliver debugging info. Other options include changing the level of verbosity etc.

Doug,

I have to agree that using global is horrible, but I have a hard time getting around it most of the time. Currently I’m working on a GUI which requires three script files to run. I’m dealing with 60+ variables that must be passed from one script to the next. From my perspective, it doesn’t seem practical to use a function that requires more than 60 inputs. It drives me crazy to see lines of code that extend off to the right of the editor. So is there a way to pass that many varibles without using global? It just seems way more convenient…But I hate using them, so if you have any insight, that’d be great!

Caitlyn

When you say script, I think you mean function as you do not pass variables to a script.

If these are all related variables, would it be better to save them into a structure? Then you can pass around a few structures. This has the added advantage of being able to keep the same function signature yet add more fields to the structure as you need more data sent to those functions.

Doug

Hi Doug,
I am working on a GUI right now, that contains a huge number of buttons and panels etc. and all the callback functions are in the .m file. Even if for every callback I write a separate function, that is called by the callback, the .m file is still huge and confusing. Is there a way to structure such .m files logically?

@Christine,
I sometimes find that putting callbacks (and other subfunctions I may need) in separate m-files makes them more manageable. I’m not sure what you mean by “the .m file is still huge and confusing”? It should be much shorter if you remove the callbacks! Just to be clear, you don’t need a callback function in the main m-file to call a separate callback function elsewhere; just make sure the separate m-file is referenced properly for the uicontrol, uipanel, etc.

@ Matt
Thanks for your response! Can you give me an example how to reference the separate m-file properly for a uicontrol? Maybe you know some sample program, that I could have a look at. By the way, I am using guide to create the GUI.

How would you avoid using eval when you have to rename a variable using the string from a cell array and then have to save the new variable as a mat file?
example:

[pathstr name]=fileparts(Cellarray{i});
exp1=[name,’=varname’];
eval(exp1);
clear varname pathstr
exp2=[‘save ‘,name,’.mat ‘,name];
eval(exp2);

where Cellarray is cell array that contains only the filename.ext not the path and varname is a matrix from loop. Also function should not require user interaction other than initial function call, hence the need for eval. any suggestions would be much appreciated.

Roger,

So the save part is easy:

save(filename, name)

The other bit about making a variable of a name known only as a string is more challenging. Often I would think there is just a better thing to do than that. However, you can use the command assignin to do something like this.

Doug

Thanks Doug!
After seeing what assignin did, I can see how it can replace what I wrote earlier. The modified lines are now:

[ pathstr NAME ] = fileparts( Cellarray { i });
assignin ( ‘base’, [NAME, ‘string1′], VAR)
save( [NAME, ‘string2′, ‘.mat’], NAME2)
clearvars -except Cellarray __ __ __

It just takes the filename.ext stored in Cellarray and then the fileparts function is used to get the name of the ith cell. Then assignin is used here to create a new variable NAME that has the same values as variable VAR. Then that new variable created called NAME2 (=[name, ‘string1′] above) is saved as a .mat file. Then all variables are cleared except for Cellarray and other necessary variables shown as ___. The name of both the new variable and the .mat file can be easily changed based on string operations. But I only needed to add an extra string to the new variable name. Thanks again and hope others find this useful.

Roger:

Use dynamic field names (Doug’s “.parens notation”) in conjunction with SAVE’s -struct flag.

% Create a string for the “variable name”
str = ‘myvariable';

% Dynamic field names
mydata.(str) = magic(5);

% SAVE the structure
save mymatfile.mat -struct mydata;

% The previous step could be written using
% the function form of SAVE if the MAT-file
% name was stored in a variable.
%
% matfilename = ‘mymatfile.mat';
% save(matfilename, ‘-struct’, ‘mydata’);

% Check that the MAT-file contains the “variable”
whos -file mymatfile.mat

To avoid “poofing” the variable into the workspace when you LOAD, call LOAD with an output argument and refer to the variable using dynamic field names again.

mydata = load(‘mymatfile.mat’);
str = ‘myvariable';
y = mydata.(str);

To me, the worst code practice I can imagine is use of function handles. I use matlab practically every day, and it is my main tool since 1996. Matlab was always very consistent in syntax – outputs to the left of =, function name, arguments in brackets. Other operators were also very clear and math-mind oriented. That all changed to me when function handles were introduced. The idea is great, but the syntax implementation is so awful and out of line relative to the rest of matlab that to day I still don’t know how to use them properly. Part of it is me refusing to learn it because I don’t want to accept that monster of ill-conceived syntax as part of my coding. The @, followed by brackets with list of input variables, that don’t have to be there either but could, followed by space! followed by function name (that doesn’t have to be there either but could), followed by inline code or not, just horrible, and it feels like someone was trying hard to make it as far from the good old consistent matlab logic as possible.

Doug,

If I have a large set of parameters shared by several functions, which is the best alternative to global?.

Thanks in advance!

Here’s a tiny tip for globals if you are concerned about naming conflicts: Always only have a *single* global variable for a given project. That can then be a struct with many fields.

Often people use globals when they really just want a persistent variable. Use “persistent” for that.

@Pepe,

I prefer passing them explicitly. One of the big dangers of globals is that variable get modified silently and you don’t know who did it. Overwhelmingly, the times I see globals used is when people do not understand how the scoping of variables works. They will start out each function with

Global PARAM PARAM PARAM PARAM x 30

So they just copy and paste the same block of globals everywhere. It gets really ugly.

Aslak had some idea with large structures to limit the amount of variables passed. Persistent is often good too. In UIs, getappdata and setappdata are good.

Add A Comment

What is 3 + 5?

Preview: hide

These postings are the author's and don't necessarily represent the opinions of MathWorks.