Marouen
Marouen

Reputation: 945

Matlab R2014a - defining a variable after a function is called

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

Answers (3)

Jens Boldsen
Jens Boldsen

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

Dennis Jaheruddin
Dennis Jaheruddin

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

gire
gire

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

Related Questions