Related
Background -- I was reading up on accessing shadowed functions, and started playing with builtin . I wrote a little function:
function klear(x)
% go to parent environment...
evalin('base', builtin('clear','x')) ;
end
This throws the error:
Error using clear
Too many output arguments.
I think this happens because evalin demands an output from whatever it's being fed, but clear is one of the functions which has no return value.
So two questions: am I interpreting this correctly, and if so, is there an alternative function that allows me to execute a function in the parent environment (that doesn't require an output)?
Note: I'm fully aware of the arguments against trying to access shadowed funcs (or rather, to avoid naming functions in a way that overload base funcs, etc). This is primarily a question to help me learn what can and can't be done in MATLAB.
Note 2
My original goal was to write an overload function that would require an input argument, to avoid the malware-ish behavior of clear, which defaults to deleting everything. In Q&D pseudocode,
function clear(x)
if ~exist('x','var') return
execute_in_base_env(builtin(clear(x)))
end
There's a couple issues with your clear override:
It will always clear in the base workspace regardless of where it's called from.
It doesn't support multiple inputs, which is a common use case for clear.
Instead I'd have it check for whether it was called from the base workspace, and special-case that for your check for whether it's clearing everything. If some function is calling plain clear to clear all its variables, that's bad practice, but it's still how that function's logic works, and you don't want to break that. Otherwise it could error, or worse, return incorrect results.
So, something like this:
function clear(varargin)
stk = dbstack;
if numel(stk) == 1 && (nargin == 0 || ismember('all', varargin))
fprintf('clear: balking at clearing all vars in base workspace. Nothing cleared.\n');
return;
end
% Check for quoting problems
for i = 1:numel(varargin)
if any(varargin{i} == '''')
error('You have a quote in one of your args. That''s not valid.');
end
end
% Construct a clear() call that works with evalin()
arg_strs = strcat('''', varargin, '''');
arg_strs = [{'''clear'''} arg_strs];
expr = ['builtin(' strjoin(arg_strs, ', '), ')'];
% Do it
evalin('caller', expr);
end
I hope it goes without saying that this is an atrocious hack that I wouldn't recommend in practice. :)
What happens in your code:
evalin('base', builtin('clear','x'));
is that builtin is evaluated in the current context, and because it is used as an argument to evalin, it is expected to produce an output. It is exactly the same as:
ans = builtin('clear','x');
evalin('base',ans);
The error message you see occurs in the first of those two lines of code, not in the second. It is not because of evalin, which does support calling statements that don't produce an output argument.
evalin requires a string to evaluate. You need to build this string:
str = 'builtin(''clear'',''x'')';
evalin('base',ans);
(In MATLAB, the quote character is escaped by doubling it.)
You function thus would look like this:
function clear(var)
try
evalin('base',['builtin(''clear'',''',var,''')'])
catch
% ignore error
end
end
(Inserting a string into another string this way is rather awkward, one of the many reasons I don't like eval and friends).
It might be better to use evalin('caller',...) in this case, so that when you call the new clear from within a function, it deletes something in the function's workspace, not the base one. I think 'base' should only be used from within a GUI that is expected to control variables in the user's workspace, not from a function that could be called anywhere and is expected (by its name in this case) to do something local.
There are reasons why this might be genuinely useful, but in general you should try to avoid the use of clear just as much as the use of eval and friends. clear slows down program execution. It is much easier (both on the user and on the MATLAB JIT) to assign an empty array to a variable to remove its contents from memory (as suggested by rahnema1 in a comment. Your base workspace would not be cluttered with variables if you used function more: write functions, not scripts!
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 have a file funcs.m that stores anonymous functions. They must be usable by the files in the directory where it is. Currently, I use the anonymous functions so that I execute the file funcs.m in different files but I think this is a a wrong way of doing things. The other functions such as main.m and its nested function nest.m need to use the anonymous functions from funcs.m. I think paths won't solve this problem because the files are in the same folder. Basically I could solve this problem by copy-pasting the anonymous functions to every file but code-smell so:
Is there some way of reusing the funcs.m having the anon functions in Matlab?
Example
main.m
function main
funcs; % loads the anonymous functions
nest(par1,...,parN)
end
nest.m
function nest(par1,...,parN)
funcs; %ERRR: This fires err, why? Look: this was sourced already in main.m!
function neededOnlyHere(par100)
bq(q,A) %This needs the functions of the funcs
end
neededOnlyHere(somePar) %ERR to use the anon funcs from funcs
end
Functions main.m and nest.m use this function funcs.m having the anonymous funcs
bq=#(q,A) q*A; %Bolded q
I=#(ii,jj,A) find(A(ii,:)==1 & A(jj,:)==0);
AiNotj=zeros(1,Ncut);
...
ERROR
Attempt to add "bq" to a static workspace.
See MATLAB Programming, Restrictions on
Assigning to Variables for details.
Error in funcs (line 10)
bq=#(q,A) q*A;
%Bolded q
Why it's breaking
You get the error when calling it in nest.m because having a nested function makes its enclosing function's workspace a "static workspace"; that is, variable names cannot be added via eval(), assignin(), or other "dynamic" techniques; only variables that are explicitly assigned in that function's text are allowed. Evaluating a script to define local variables - which is what you're doing when calling funcs.m - is "dynamic", so prohibited in functions with nested functions. It works in main.m because main has no nested functions and is thus a "dynamic" workspace.
There are a couple ways you could change it to work with static workspaces and nested functions. The first thing to ask is whether you really need to make them anonymous functions?
Using package functions instead
If you don't need them to be anonymous functions per se, just break them out and put each one as a regular function in its own .m file; e.g. bg.m, I.m, AiNotj.m, and so on. Then they're all available to all other functions in that directory.
If that turns in to a mess of files, or if you want to scope them and maybe make them available only to the selected functions that really need them (that is, the functions currently calling funcs()), then you can stick them in a package. Create a subdirectory called +myfuncs and move all the little function files in there; e.g. +myfuncs/bq.m, +myfuncs/I.m, +myfuncs/AiNotj.m. (The + prefix tells Matlab the directory is a package.) Then you can pull all of them in to your function scope by doing import myfuncs.* as a direct replacement for where you're currently calling funcs().
function nest(par1,...,parN)
import myfuncs.*;
function neededOnlyHere(par100)
bq(q,A) % This will work, resolving to myfuncs.bq
end
You can do the import myfuncs.* from the command line to make them available interactively, too.
This is probably how Matlab itself wants you to organize clusters of related functions like this, and would be my first approach. It's the least "smelly" IMHO. If you really wanted to be able to edit them all in a single file like funcs.m for convenience, you could write a little code munger in Perl or whatever that parsed funcs.m and output them all as equivalent individual functions as a preprocessing step. (I think it's a bit of a bummer that you can't define multiple top-level functions in an M-file like this, but oh well.)
If you really need to work with anonymous functions, there are some workarounds.
Passing functions in a struct
You can change your funcs() function to actually return a struct of all those anonymous functions, using field names instead of local variable names.
function out = funcs
out.bq=#(q,A) q*A; %Bolded q
out.I=#(ii,jj,A) find(A(ii,:)==1 & A(jj,:)==0);
out.AiNotj=zeros(1,Ncut);
For this, you'd have to prefix all the function references with the struct name you're holding them in. Don't know how big a deal this is for you.
function nest(par1,...,parN)
fs = funcs;
function neededOnlyHere(par100)
fs.bq(q,A) %This needs the functions of the funcs
end
Preallocating variables
To get funcs() to work as-is, you can statically pre-allocate variables with all the function names you're going to use, so the Matlab parser recognizes them as statically assigned variables. Then when you call funcs(), it will re-assign the values of the existing variables, which is permissible in dynamic workspaces.
function nest(par1,...,parN)
[bq, I, AiNotj] = deal(); % Preallocate all names from funcs
funcs;
function neededOnlyHere(par100)
bq(q,A) %This needs the functions of the funcs
end
This would be a bit of a pain, because you'd have to re-edit every file that uses funcs whenever a new function name is added. You could at least write a little perl script to auto-generate that line of code by parsing funcs.m and outputting a "[bg, I, AiNotj,...] = deal();" with all the functions it finds, and you can just copy that in to your code.
Another way to do this would be to have funcs actually return all the functions in its output list. This would have the benefit of continuing to work even as you add new functions to funcs.m, as long as you don't remove or change the order of your existing anonymous functions.
function [bg,I,AiNotj] = funcs()
bg = ...
I = ...
% And then in the calling functions:
[bg,I,AiNotj] = funcs(); % which you can copy and paste from funcs.m's header
There are many ways of passing anonymous functions:
1) Pass the function itself:
function main
f = #(t) t^2 - 3;
param = randn(12,1);
g = test22(param,f);
disp (g)
end
function g = test22(param,f)
g = f(param(2));
disp(param(2))
end
2) Use globals (which usually should be avoided in complex code)
function main
global f
f = #(t) t^2 - 3;
param = randn(12,1);
g = test22(param);
disp (g)
end
function g = test22(param)
global f
g = f(param(2));
disp(param(2))
end
function y = myfunc(param)
C = param.C;
L = param.L;
Kp = param.Kp;
Ki = param.Ki;
...
Is there a way to generalize the above code? I know how to generalize the structure access using fieldnames() and getfield(), but not how to set variables without calling eval() (which is evil).
for n = fieldnames(param)'
name = n{1};
value = param.(name);
do_something_with(name,value); % ????
never mind, I figured it out; this helper function works:
function vars_pull(s)
for n = fieldnames(s)'
name = n{1};
value = s.(name);
assignin('caller',name,value);
end
The only way to create a variable whose name is determined at run-time is to use a function like eval, evalin, feval, or assignin. (assignin is the least evil choice BTW, at least you don't need to convert your value to a string and back.)
However, I question why you want to do that, why not just access the values through the input structure as you need them. If you want to save typing (speaking from experience, as I am extremely lazy), I usually name my input parameter structure something short, like p. The throughout my code I just access the fields directly, (e.g. p.Kp, and after a while I don't even see the p. anymore.) This also makes it easy to pass the structure into subfunctions as needed.
You can use the excellent submission at FileExchange:
V2STRUCT - Pack & Unpack variables to & from structures with enhanced functionality
Here's a workaround: save the structure to a .mat file using the '-struct' option, and then immediately reload it. Here's an example for struct variable X:
save('deleteme.mat','-struct','X');
load('deleteme.mat');
delete('deleteme.mat');
It's kludgey, but actually pretty fast, at least with an SSD.