- If the one-shot function is not that complicated, then you could always use an anonymous one.
- You always have the alternative of making the script a function. It's just an extra line. There's no big difference between them and you can put as many one-shot functions inside it as you'd like.
A way to work around MATLAB's inability of put a local function into M-script
7 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Kouichi C. Nakamura
el 6 de Jul. de 2016
Comentada: Kouichi C. Nakamura
el 15 de Sept. de 2016
I have been wondering why we are not allowed to put a local function in a script file. According to related threads below, it seems that I am not the only one.
Down side of creating functions that are only to be used for a specific script might be...
- Names: If you keep doing this, your folder will be cluttered with lots of one-shot functions, and it is highly likely that you end up having lots of them with very similar and confusing names. Once you loose the track of record, you might not able to work out which function is right for you.
- Scope: Closely related to the above. Functions that are put in a folder are within the scope of all other files in the folder, or if the folder is in the MATLAB search path, of all the MATLAB files. Frequently used utility functions and those one-shot functions will be mixed up. Finding a right function may become more difficult with lots of other candidates with confusing names. Ideally, your one-shot functions should be only visible to the script that they were dedicated to.
- Maintenance: If you have to prepare five separate function .m files for one script, it would be more prone to loose their integrity, when copied to other place or people, for example. One-shot functions should better be kept in one place for maintenance.
I've been thinking about this, and came up with a very basic approach that can work around most of the above issues, albeit not entirely.
1. Use date-based sequential stem name for script file. A name like "scr2016_07_05_200000_xxxxx.m" may be beneficial, in that all the script and related files (html, mlx, pdf) will be shown in date order. It is easy to relate these sibling files. Also, it is useful to remember what you were up to on a specific day. Sequential numbering is a great way to avoid the pain of thinking of a unique name for just simple scripts.
2. Deploy a utility class with static methods. Create a classdef file with the name "scr2016_07_05_200000_xxxxx_util.m" Leave properties empty and put an attribute (Static) to methods as below. And then, you can add as many static functions as you want here.
classdef scr2016_07_05_200000_xxxxx_util
%scr2016_07_05_200000_xxxxx_util
properties
end
methods (Static)
function out1 = func1(var1, var2)
end
function out2 = func2(var3, varargin)
end
end
end
3. In your script, call an instance of "scr2016_07_05_200000_xxxxx_util" as below (Note you don't have to create an object to use Static methods. classname.staticMethodName(args,...) works. Below is just to avoid repeating lengthy class names.):
u = scr2016_07_05_200000_xxxxx_util;
4. Then, you can access to the static functions like this.
C = u.func1(A,B)
Benefit of this approach so far may be...
- Scope of those static methods are limited.
- You can find all of the related function in one place.
- You don't have to worry about thinking of absolutely unique function names every time. You only have to worry about uniqueness within the class, which is pretty easy.
- In essence, your script will have a twin brother of a dedicated utility class. I found that working on a .m or .mlx script and the classdef .m file side by side in one screen was extremely efficient. Your script will show abstract code on the left, and detailed workings in static methods in the classdef file on the right.
I'd like to hear your even better ideas or constructive feedback.
Thank you for reading.
Best, Kouichi
7 comentarios
Guillaume
el 7 de Jul. de 2016
Editada: Guillaume
el 7 de Jul. de 2016
This is deviating quite a lot from the original question, but anyway the way I usually cope with this sort of top level function/script that may need restarting in case of issues/crash/abort is to actually use a class. This has several advantages:
All the default constants that you would define in your scripts, they can just be the default values of the properties of your class.
If the user wants to modify some of the constants. Easy, just change the given properties.
You can save the object to a mat file, so that you have a record of the settings used without needing to modify the source code. Good for version control. You need to reprocess the data with whatever settings you used a year ago. Reload the object from the mat file.
You can have a method that starts the processing from the beginning and a similar method that resumes from where it left off.
E.g.:
classdef DropSizer < handle
properties (Access = public)
SizeThreshold = 20;
EdgeWidth = 10;
%...
end
methods
function Run(this, imagelist)
state = struct('ImageList', imagelist, 'CurrentIndex', 0);
this.Process(state);
end
function Resume(this, resumestate)
this.Process(resumestate);
end
end
methods (Access = Private)
function Process(this, state)
%processing may take a long time and crash
while state.CurrentIndex < numel(state.ImageList)
currentimage = state.ImageList(state.CurrentIndex + 1);
%entering procedure that may error
try
%do something
catch exception
fprintf(2, '<strong>While processing image index %u</strong>:\n', state.CurrentIndex + 1);
fprintf(2, '%s\n', exception.message);
assignin('base', 'resumestate', state); %store in base workspace or you could save to mat
return;
end
state.CurrentIndex = state.CurrentIndex + 1;
end
end
end
end
My functions are actually function objects which I find a lot neater when you want to deal with optional inputs (they're properties with default instead).
Respuesta aceptada
Friedrich
el 7 de Jul. de 2016
Hi,
how about giving 16b a shot? Just do it ;)
3 comentarios
Guillaume
el 7 de Jul. de 2016
I would have thought the first thing you'd do on downloading the pre-release is to look at the release note to see what's new.
It's the first entry under Language and Programming.
Más respuestas (2)
Steven Lord
el 15 de Sept. de 2016
Release R2016b is now officially available. As listed in the first item in the Language and Programming section of the Release Notes for MATLAB in that release, you can now define local functions in script files.
Ver también
Categorías
Más información sobre System Commands en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!