Related
Suppose we have
Check.m:
classdef Check < handle
methods (Static)
function doStuff()
if isCalledFromAssertSubclass
% do this stuff only if called as Assert.doStuff(), not if called as Check.doStuff()
end
% do other stuff
end
end
end
and Assert.m:
classdef Assert < Check
% nop
end
As written in the comment, I would like to have that Check.doStuff() executes only the "do other stuff" line and that Assert.doStuff() executes the if isCalledFromAssertSubclass block as well.
I want to use static methods, so that I don't neet to create an Assert object whenever I need an assert. Using a global assert object is also very ugly and needs a global assert line in each function I want to use an assert. Likewise for checks.
So there are two problems:
Since these are static classes, there is no chance of using class(obj) or any other non-static class property or function.
dbstack is not inheritance aware and always returns Check as calling class, also for Assert.doStuff.
I did find a working solution, which uses a combination of dbstack and dbtype to read the line where the call came from, i.e. the line where it says Assert.doStuff(). However it involves two debug functions which probably should not be used in productive code and more importent, dbtype is very slow (in my case, 30 our of 70 seconds!).
I could use a package instead (directory +Check with function files in there) and create a symlink +Assert -> +Check. Then I could check the file name, but that's a) not portable, b) quite ugly and c) also somewhat slow (I suppose).
Is there any faster method for this?
Why not overload the static method for Assert, and have it call the parent's method when it's done? This is the normal way of using inheritance: you don't want the parent, Check, to know anything about its child, Assert.
This is what it would look like:
classdef Assert < Check
methods (Static)
function doStuff()
% do some stuff
Check.doStuff()
end
end
end
As #Wolfie suggests in a comment, the above works as long as Check.doStuff is not sealed. A sealed method cannot be overloaded. See the documentation.
When I was studying for my undergraduate degree in EE, MATLAB required each function to be defined in its own file, even if it was a one-liner.
I'm studying for a graduate degree now, and I have to write a project in MATLAB. Is this still a requirement for newer versions of MATLAB?
If it is possible to put more than one function in a file, are there any restrictions to this? For instance, can all the functions in the file be accessed from outside the file, or only the function that has the same name as the file?
Note: I am using MATLAB release R2007b.
The first function in an m-file (i.e. the main function), is invoked when that m-file is called. It is not required that the main function have the same name as the m-file, but for clarity it should. When the function and file name differ, the file name must be used to call the main function.
All subsequent functions in the m-file, called local functions (or "subfunctions" in the older terminology), can only be called by the main function and other local functions in that m-file. Functions in other m-files can not call them. Starting in R2016b, you can add local functions to scripts as well, although the scoping behavior is still the same (i.e. they can only be called from within the script).
In addition, you can also declare functions within other functions. These are called nested functions, and these can only be called from within the function they are nested. They can also have access to variables in functions in which they are nested, which makes them quite useful albeit slightly tricky to work with.
More food for thought...
There are some ways around the normal function scoping behavior outlined above, such as passing function handles as output arguments as mentioned in the answers from SCFrench and Jonas (which, starting in R2013b, is facilitated by the localfunctions function). However, I wouldn't suggest making it a habit of resorting to such tricks, as there are likely much better options for organizing your functions and files.
For example, let's say you have a main function A in an m-file A.m, along with local functions D, E, and F. Now let's say you have two other related functions B and C in m-files B.m and C.m, respectively, that you also want to be able to call D, E, and F. Here are some options you have:
Put D, E, and F each in their own separate m-files, allowing any other function to call them. The downside is that the scope of these functions is large and isn't restricted to just A, B, and C, but the upside is that this is quite simple.
Create a defineMyFunctions m-file (like in Jonas' example) with D, E, and F as local functions and a main function that simply returns function handles to them. This allows you to keep D, E, and F in the same file, but it doesn't do anything regarding the scope of these functions since any function that can call defineMyFunctions can invoke them. You also then have to worry about passing the function handles around as arguments to make sure you have them where you need them.
Copy D, E and F into B.m and C.m as local functions. This limits the scope of their usage to just A, B, and C, but makes updating and maintenance of your code a nightmare because you have three copies of the same code in different places.
Use private functions! If you have A, B, and C in the same directory, you can create a subdirectory called private and place D, E, and F in there, each as a separate m-file. This limits their scope so they can only be called by functions in the directory immediately above (i.e. A, B, and C) and keeps them together in the same place (but still different m-files):
myDirectory/
A.m
B.m
C.m
private/
D.m
E.m
F.m
All this goes somewhat outside the scope of your question, and is probably more detail than you need, but I thought it might be good to touch upon the more general concern of organizing all of your m-files. ;)
Generally, the answer to your question is no, you cannot define more than one externally visible function per file. You can return function handles to local functions, though, and a convenient way to do so is to make them fields of a struct. Here is an example:
function funs = makefuns
funs.fun1=#fun1;
funs.fun2=#fun2;
end
function y=fun1(x)
y=x;
end
function z=fun2
z=1;
end
And here is how it could be used:
>> myfuns = makefuns;
>> myfuns.fun1(5)
ans =
5
>> myfuns.fun2()
ans =
1
The only way to have multiple, separately accessible functions in a single file is to define STATIC METHODS using object-oriented programming. You'd access the function as myClass.static1(), myClass.static2() etc.
OOP functionality is only officially supported since R2008a, so unless you want to use the old, undocumented OOP syntax, the answer for you is no, as explained by #gnovice.
EDIT
One more way to define multiple functions inside a file that are accessible from the outside is to create a function that returns multiple function handles. In other words, you'd call your defining function as [fun1,fun2,fun3]=defineMyFunctions, after which you could use out1=fun1(inputs) etc.
I really like SCFrench's answer - I would like to point out that it can easily be modified to import the functions directly to the workspace using the assignin function. (Doing it like this reminds me a lot of Python's "import x from y" way of doing things)
function message = makefuns
assignin('base','fun1',#fun1);
assignin('base','fun2',#fun2);
message='Done importing functions to workspace';
end
function y=fun1(x)
y=x;
end
function z=fun2
z=1;
end
And then used thusly:
>> makefuns
ans =
Done importing functions to workspace
>> fun1(123)
ans =
123
>> fun2()
ans =
1
Along the same lines as SCFrench's answer, but with a more C# style spin..
I would (and often do) make a class containing multiple static methods. For example:
classdef Statistics
methods(Static)
function val = MyMean(data)
val = mean(data);
end
function val = MyStd(data)
val = std(data);
end
end
end
As the methods are static you don't need to instansiate the class. You call the functions as follows:
data = 1:10;
mean = Statistics.MyMean(data);
std = Statistics.MyStd(data);
I define multiple functions in one .m file with Octave and then use the command from within the .m file where I need to make use of the functions from that file:
source("mycode.m");
Not sure if this is available with Matlab.
octave:8> help source
'source' is a built-in function
-- Built-in Function: source (FILE)
Parse and execute the contents of FILE. This is equivalent to
executing commands from a script file, but without requiring the
file to be named `FILE.m'.
You could also group functions in one main file together with the main function looking like this:
function [varargout] = main( subfun, varargin )
[varargout{1:nargout}] = feval( subfun, varargin{:} );
% paste your subfunctions below ....
function str=subfun1
str='hello'
Then calling subfun1 would look like this:
str=main('subfun1')
As of R2017b, this is not officially possible. The relevant documentation states that:
Program files can contain multiple functions. If the file contains only function definitions, the first function is the main function, and is the function that MATLAB associates with the file name. Functions that follow the main function or script code are called local functions. Local functions are only available within the file.
However, workarounds suggested in other answers can achieve something similar.
I have try with the SCFRench and with the Ru Hasha on octave.
And finally it works: but I have done some modification
function message = makefuns
assignin('base','fun1', #fun1); % Ru Hasha
assignin('base', 'fun2', #fun2); % Ru Hasha
message.fun1=#fun1; % SCFrench
message.fun2=#fun2; % SCFrench
end
function y=fun1(x)
y=x;
end
function z=fun2
z=1;
end
Can be called in other 'm' file:
printf("%d\n", makefuns.fun1(123));
printf("%d\n", makefuns.fun2());
update:
I added an answer because neither the +72 nor the +20 worked in octave for me.
The one I wrote works perfectly (and I tested it last Friday when I later wrote the post).
When I was studying for my undergraduate degree in EE, MATLAB required each function to be defined in its own file, even if it was a one-liner.
I'm studying for a graduate degree now, and I have to write a project in MATLAB. Is this still a requirement for newer versions of MATLAB?
If it is possible to put more than one function in a file, are there any restrictions to this? For instance, can all the functions in the file be accessed from outside the file, or only the function that has the same name as the file?
Note: I am using MATLAB release R2007b.
The first function in an m-file (i.e. the main function), is invoked when that m-file is called. It is not required that the main function have the same name as the m-file, but for clarity it should. When the function and file name differ, the file name must be used to call the main function.
All subsequent functions in the m-file, called local functions (or "subfunctions" in the older terminology), can only be called by the main function and other local functions in that m-file. Functions in other m-files can not call them. Starting in R2016b, you can add local functions to scripts as well, although the scoping behavior is still the same (i.e. they can only be called from within the script).
In addition, you can also declare functions within other functions. These are called nested functions, and these can only be called from within the function they are nested. They can also have access to variables in functions in which they are nested, which makes them quite useful albeit slightly tricky to work with.
More food for thought...
There are some ways around the normal function scoping behavior outlined above, such as passing function handles as output arguments as mentioned in the answers from SCFrench and Jonas (which, starting in R2013b, is facilitated by the localfunctions function). However, I wouldn't suggest making it a habit of resorting to such tricks, as there are likely much better options for organizing your functions and files.
For example, let's say you have a main function A in an m-file A.m, along with local functions D, E, and F. Now let's say you have two other related functions B and C in m-files B.m and C.m, respectively, that you also want to be able to call D, E, and F. Here are some options you have:
Put D, E, and F each in their own separate m-files, allowing any other function to call them. The downside is that the scope of these functions is large and isn't restricted to just A, B, and C, but the upside is that this is quite simple.
Create a defineMyFunctions m-file (like in Jonas' example) with D, E, and F as local functions and a main function that simply returns function handles to them. This allows you to keep D, E, and F in the same file, but it doesn't do anything regarding the scope of these functions since any function that can call defineMyFunctions can invoke them. You also then have to worry about passing the function handles around as arguments to make sure you have them where you need them.
Copy D, E and F into B.m and C.m as local functions. This limits the scope of their usage to just A, B, and C, but makes updating and maintenance of your code a nightmare because you have three copies of the same code in different places.
Use private functions! If you have A, B, and C in the same directory, you can create a subdirectory called private and place D, E, and F in there, each as a separate m-file. This limits their scope so they can only be called by functions in the directory immediately above (i.e. A, B, and C) and keeps them together in the same place (but still different m-files):
myDirectory/
A.m
B.m
C.m
private/
D.m
E.m
F.m
All this goes somewhat outside the scope of your question, and is probably more detail than you need, but I thought it might be good to touch upon the more general concern of organizing all of your m-files. ;)
Generally, the answer to your question is no, you cannot define more than one externally visible function per file. You can return function handles to local functions, though, and a convenient way to do so is to make them fields of a struct. Here is an example:
function funs = makefuns
funs.fun1=#fun1;
funs.fun2=#fun2;
end
function y=fun1(x)
y=x;
end
function z=fun2
z=1;
end
And here is how it could be used:
>> myfuns = makefuns;
>> myfuns.fun1(5)
ans =
5
>> myfuns.fun2()
ans =
1
The only way to have multiple, separately accessible functions in a single file is to define STATIC METHODS using object-oriented programming. You'd access the function as myClass.static1(), myClass.static2() etc.
OOP functionality is only officially supported since R2008a, so unless you want to use the old, undocumented OOP syntax, the answer for you is no, as explained by #gnovice.
EDIT
One more way to define multiple functions inside a file that are accessible from the outside is to create a function that returns multiple function handles. In other words, you'd call your defining function as [fun1,fun2,fun3]=defineMyFunctions, after which you could use out1=fun1(inputs) etc.
I really like SCFrench's answer - I would like to point out that it can easily be modified to import the functions directly to the workspace using the assignin function. (Doing it like this reminds me a lot of Python's "import x from y" way of doing things)
function message = makefuns
assignin('base','fun1',#fun1);
assignin('base','fun2',#fun2);
message='Done importing functions to workspace';
end
function y=fun1(x)
y=x;
end
function z=fun2
z=1;
end
And then used thusly:
>> makefuns
ans =
Done importing functions to workspace
>> fun1(123)
ans =
123
>> fun2()
ans =
1
Along the same lines as SCFrench's answer, but with a more C# style spin..
I would (and often do) make a class containing multiple static methods. For example:
classdef Statistics
methods(Static)
function val = MyMean(data)
val = mean(data);
end
function val = MyStd(data)
val = std(data);
end
end
end
As the methods are static you don't need to instansiate the class. You call the functions as follows:
data = 1:10;
mean = Statistics.MyMean(data);
std = Statistics.MyStd(data);
I define multiple functions in one .m file with Octave and then use the command from within the .m file where I need to make use of the functions from that file:
source("mycode.m");
Not sure if this is available with Matlab.
octave:8> help source
'source' is a built-in function
-- Built-in Function: source (FILE)
Parse and execute the contents of FILE. This is equivalent to
executing commands from a script file, but without requiring the
file to be named `FILE.m'.
You could also group functions in one main file together with the main function looking like this:
function [varargout] = main( subfun, varargin )
[varargout{1:nargout}] = feval( subfun, varargin{:} );
% paste your subfunctions below ....
function str=subfun1
str='hello'
Then calling subfun1 would look like this:
str=main('subfun1')
As of R2017b, this is not officially possible. The relevant documentation states that:
Program files can contain multiple functions. If the file contains only function definitions, the first function is the main function, and is the function that MATLAB associates with the file name. Functions that follow the main function or script code are called local functions. Local functions are only available within the file.
However, workarounds suggested in other answers can achieve something similar.
I have try with the SCFRench and with the Ru Hasha on octave.
And finally it works: but I have done some modification
function message = makefuns
assignin('base','fun1', #fun1); % Ru Hasha
assignin('base', 'fun2', #fun2); % Ru Hasha
message.fun1=#fun1; % SCFrench
message.fun2=#fun2; % SCFrench
end
function y=fun1(x)
y=x;
end
function z=fun2
z=1;
end
Can be called in other 'm' file:
printf("%d\n", makefuns.fun1(123));
printf("%d\n", makefuns.fun2());
update:
I added an answer because neither the +72 nor the +20 worked in octave for me.
The one I wrote works perfectly (and I tested it last Friday when I later wrote the post).
I know that I can use a class consisting solely of static methods to implement a namespace in MATLAB. E.g.
classdef MyNamespace
methods (Static = true)
function [...] = foo(...)
...
end
function [...] = bar(...)
...
end
...
end
end
With the above I can call functions MyNamespace.foo, MyNamespace.bar, etc. (assuming, of course, that the file MyNamespace.m is in my search path, or in the current directory).
A paramount feature of this technique is that it allows simulating "namespace variables". For example, a function within the methods (Static = true) could have the form
function out = BAZ(newval)
persistent val;
out = val;
if nargin > 0, val = newval; end
end
With this, the method MyNamespace.BAZ can mimic a "namespace variable" MyNamespace.BAZ (though, admittedly, in a very cumbersome way).
This feature is one that I absolutely require.
The implementation of namespaces described above is ok, but I'd like to be able import namespace, so that I can call their functions using their "short" (aka "unqualified") names, such as foo, bar, etc.
How can I implement a namespace that can be imported, in the sense described above?
BTW, I'd prefer answers that build on the technique illustrated above (for implementing namespaces), since it's a technique I have some experience with, but I'm also open to alternatives that are not based on this technique.
MATLAB has a package system which allows creating a namespace of functions which are also importable. In short, just drop a directory whose name begins with a + in another directory on your path and add your function MATLAB files in that directory. If you have MyNamespace.m in the directory someDir then just create:
someDir/+MyNamespace/foo.m
someDir/+MyNamespace/bar.m
and so on. You can call them via MyNamespace.foo, MyNamespace.bar and import them:
import MyNamespace.foo
or:
import MyNamespace.*
I am trying to implement a small example function in Matlab OOP.
The functioning code is:
classdef Cat < handle
properties
meowCount = 0;
end
methods
function obj = Cat() % all initializations, calls to base class, etc. here,
end
function Meow(obj)
disp('meowww');
obj.meowCount = obj.meowCount + 1;
end
end
end
I want to create something of the following sort akin to C++ as my real life function definitions are very big and I don't want to clutter my class definition:
classdef Cat < handle
properties
meowCount = 0;
end
methods
function obj = Cat() % all initializations, calls to base class, etc. here,
end
function Meow(obj);
end
end
%%
function Cat::Meow(obj)
disp('meowww');
obj.meowCount = obj.meowCount + 1;
end
So, basically write the definition of function Meow outside the class. How do I accomplish the above change ?
To play with the working first version you can use the following:
C = Cat;
C.meowCount
C.Meow
Create a folder called #Cat.
The within #Cat, put the following files:
Cat.m
classdef Cat < handle
properties
meowCount = 0;
end
methods
function obj = Cat()
end
Meow(obj) % this is optional, and just indicates the function signature
end
end
Meow.m
function Meow(obj)
disp('meowww');
obj.meowCount = obj.meowCount + 1;
end
Move out of the #Cat folder, and make sure it (or its parent folder) is on your path. Then try your examples.
If you use an # folder to contain your class like this, most methods (though not constructors, and not property get/set methods) can be moved to external files.
If you want, you can include a function signature with no implementation in the main classdef file. This is sometimes optional, but if you wish to change the Access level of the method away from default, it is necessary.
There are two ways of defining methods of a class. The newer, more portable way, is by defining them within the same classdef file. You can also write methods as separate M-file functions and put them in a #MyClass folder. Note that some methods must be in the classdef file. You can still define your separate file methods as static and private via helper functions. This is a bit of hack, which is why it's a good idea to put everything in the classdef file unless you have a very large project.
The best way to deal with clutter in your classdef file is to use code-folding. You can collapse individual methods and entire method blocks. In this way you can easily organize your classdef file to be as uncluttered as possible by grouping related methods together in the same methods block. Collapse any methods/blocks you aren't using at the time.
Additionally, you can use the "Go To" button in the Editor Ribbon Tab to select a specific method to view (if they are all defined in the same file).
Writing your methods in separate files may seem like a good solution at first, but if you have a class with many methods, it becomes extremely cumbersome to have many files open at once. Unlike C++, you can only define one method per file. It really ends up being quite a mess.
See Also:
Code Folding — Expand and Collapse Code Constructs
Editor/Debugger Code Folding Preferences