Borrar filtros
Borrar filtros

How to check if variable is in workspace?

279 visualizaciones (últimos 30 días)
Christian Berwanger
Christian Berwanger el 7 de Dic. de 2017
Editada: Stephen23 el 7 de Dic. de 2017
Hello, I want to check if a variable is in workspace and use it, instead of load my data from the slower HDD. So what I do is:
if exist('Nodes','var')==0
Nodes = csvread([path mesh], 0, 0);
assignin('base','Nodes',Nodes);
err = 'Test'
end
do something;
As far as I understand this should print
err =
Test
in the first run. In the second run it shouldn't. (I used the err = 'Test' to check if my Code runs correctly).
Somehow I do get in every single run the output
err =
Test
so I always reassign Nodes. What did I do wrong?
Any suggestions?
kind regards
  1 comentario
Stephen23
Stephen23 el 7 de Dic. de 2017
Editada: Stephen23 el 7 de Dic. de 2017
@Christian Berwanger: the line
exist('Nodes','var')==0
checks if Nodes exists in the workspace where that code is run. The line
assignin('base','Nodes',Nodes);
defines a variable called Nodes in the base workspace. There are two likely scenarios:
1. your code is in a function: then each time the function is called Nodes will be undefined in the function workspace and so the file will be loaded again.
2. you are running that code in a script called from the base workspace: then assignin is totally superfluous.
So both of these scenarios are flawed.
You could resolve the first scenario by using evalin. But I would suggest that this approach is flawed as well: it will work, but it is the kind of approach that beginners use to write slow, complex, inefficient code. Beginners love spamming all of their variables into the base workspace, and get some feeling of security from looking at all of those lovely variables sitting in the Variable Viewer pane. I know, I can remember that feeling!
But relying on the base workspace is a bad way to write code. Spamming variables into the base workspace is slow and is risky (e.g. overwriting variables without warning). Those beginners also typically try to write functions that magically access the variables in the base workspace (as you are trying to do) and perform some operations on them, but all of the techniques that can achieve this are slow, complex, inefficient, and will increase the chance of bugs. For example, introspective coding (e.g. exist) is slower than simply checking for an empty array or using nargin. On top of that, calling exist in different workspace is slower still, because any magical jumping between workspace will slow your code down (conversion to string, removes JIT code acceleration, etc).
Basically your entire approach forces you to write slow, complex, inefficient code.
If you want to write simpler, neater, efficient MATLAB code then forget about magically running things in other workspaces and magically checking if something exists somewhere else or not. Also, forget about the base workspace. Simply write functions, and pass all values as input and output arguments. Checking those arguments is easy. It will also be very efficient. This is the first step to learning how to write simple, reliable code. Functions are how experienced users write reliable, efficient, testable, robust code.
See my answer for a simpler, neater, more efficient solution.
PS: you might like to read this:

Iniciar sesión para comentar.

Respuesta aceptada

Stephen23
Stephen23 el 7 de Dic. de 2017
Editada: Stephen23 el 7 de Dic. de 2017
Based on my comment to your question: a much better approach is to use persistent inside a function:
function out = myfun(inp)
% myfun is simple.
persistent mat
if isempty(mat)
mat = csvread('mydatafile.csv');
end
% do something with |mat|:
out = mat.*inp;
end
When the function is first called mat will be empty and it will load the data file. After that it will use the data stored using persistent.
Did you see what I did there? I turned your complex and buggy code into a simple solution using standard efficient MATLAB commands. No magical jumping between workspaces, inefficient string evaluation or slow introspective programming is required.
  4 comentarios
Christian Berwanger
Christian Berwanger el 7 de Dic. de 2017
Oh. yeah. Sorry. in your Code it is mat. how can I remove mat, so next run will reinitialize it?
Stephen23
Stephen23 el 7 de Dic. de 2017
Editada: Stephen23 el 7 de Dic. de 2017
@Christian Berwanger: you can either add a flag as an input argument, and use that to reload the file, something like this:
function out = myfun(inp,flag)
% myfun is simple.
persistent mat
if isempty(mat) || (nargin>1&&flag)
mat = csvread('mydatafile.csv');
end
% do something with |mat|:
out = mat.*inp;
end
Or you can clear the function:
clear myfun

Iniciar sesión para comentar.

Más respuestas (1)

KL
KL el 7 de Dic. de 2017
Editada: KL el 7 de Dic. de 2017
You're probably using this code inside a function but not the main script that uses your base workspace. That explains why you use the ugly assignin.
Don't do this. Use your functions' parameters in a better way.
If you want to load Nodes only if it'S not in the base workspace, then
%main script
chk = exist('Nodes','var');
if ~chk
Nodes = getNodes(path,mesh,0,0);
disp('Node is loaded')
else
disp('Node is already loaded')
end
and your getNodes should look like,
function Nodes = getNodes(path,mesh,a,b)
Nodes = csvread([path mesh], a, b); %maybe fullfile(path,mesh)?
end
Now there's absolutely no need for assignin.
  1 comentario
Christian Berwanger
Christian Berwanger el 7 de Dic. de 2017
I am using Matlab as a Script for a Simulation tool. My tool opens an instance of Matlab and call the function with given parameters. So: My simulation tool knows the location of the Matlab function and call it with function(x,y,z).
As Matlab deletes every variable after a function is running I need to do that assignin to keep it in the workspace. I do not have any main Script.

Iniciar sesión para comentar.

Categorías

Más información sobre Data Type Identification en Help Center y File Exchange.

Etiquetas

Productos

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by