Reputation: 945
In a matlab script, is it possible to define a variable after the function is called? (i.e. the script finds the function with the undefined variable, looks for the variable initialization and executes the function afterwards)
I need this because I have a large number of variables and functions and I don't want to order them in a sequential way but in the way that is appropriate for my problem.
E.g.
mean(x);
x = [1, 2, 3];
Thanks
Upvotes: 0
Views: 212
Reputation: 1275
If I understand you question correctly, then yes it can be done by some ugly hacks. The following class can be used:
classdef AdvancedFunctionHandle
properties(GetAccess = 'private', SetAccess = 'private')
handle
variables
end
methods
function obj = AdvancedFunctionHandle(fct, varargin)
if ~isa(fct,'function_handle')
error('The function must be a function handle!');
end
argins = numel(varargin);
variables = cell(1,argins);
for i = 1:argins
if ~ischar(varargin{i})
error('The variables must be represented by a string variabel name!');
end
if (~isvarname(varargin{i}) )
error('The variables must be a string representing a legal variabel name!');
end
variables{i} = varargin{i};
end
obj.handle = fct;
obj.variables = variables;
end
function val = subsindex(obj)
val = obj.calculate();
end
function val = calculate(obj)
try
vars = cell(1,numel(obj.variables));
for i = 1:numel(obj.variables)
v = evalin('base',obj.variables{i});
if isa(v,'AdvancedFunctionHandle')
vars{i} = v.calculate();
else
vars{i} = v;
end
end
val = obj.handle(vars{:});
catch
val = obj;
end
end
function display(obj)
disp([func2str(obj.handle),'(',strjoin(obj.variables,','),')']);
end
end
end
I made a small test script for it too:
clear
m = AdvancedFunctionHandle(@mean,'x');
s = AdvancedFunctionHandle(@(n)sum(1:n),'m');
m.calculate
x = [1,2,3];
s.calculate
I hope this solves your problem. Notice that since the class refers to the base workspace, it will not work when run from a function, or if the script it is run from is run from a function.
Upvotes: 1
Reputation: 21563
I don't understand what you are trying to achieve, but if you want to define things after they are used, I think they have to be functions.
Example file:
function myfun()
mean(getX)
function X = getX
X = [1 2 3]
So though it is technically possible to define variables after they are used, you would really not want to do that.
Upvotes: 0
Reputation: 1105
Disclaimer: I think what you want to do is a really bad practice. If you find yourself in the need to do this, your code screams refactoring.
Yes, it is possible. There are two ways.
Using the try-catch
statement:
try
x_mean = mean(x)
catch exception
if isequal(exception.identifier, 'MATLAB:UndefinedFunction')
x = [1,2,3];
x_mean = mean(x);
else
rethrow(exception);
end
end
The explanation: if the mean(x)
fails, the code will enter in the catch
branch. Then it verifies that the error is happening because a missing variable and if that's the case, the variable x
is defined and the function re-run. There is a caveat: Matlab uses the same identifier for missing variable and for missing function.
Using the exist
function:
if exist('x') == 1 %// the function have several return values
x_mean = mean(x);
else
x = [1, 2, 3];
x_mean = mean(x);
end
The explanation: the exist
function will verify if a variable with the name x
exists in the workspace. If it does exist, it will return 1 and you can execute your function. If it does not exist, then you can declare it first and then run mean
. See documentation here.
My two cents: once again, this is a horrible way to achieve things. By going this way you will end up with pure spaghetti code. It will be a nightmare to debug. It will be a nightmare to maintain. There is a 99% chance that there are better ways to do what you want. It is just a matter of investing time and think a little bit. Even if it is a personal project or a quick script to solve a homework/task, you will learn much more by doing it the right way.
Upvotes: 2