How can I assign multiple local variables by names?
For example, within a lambda, something like this:
{
#[;:;] (.') flip (`a`b;4 2);
(a;b)
}[] / should return 4 2
But obviously does not work, because
q)#[`a;:;4]
'type
Also,
q):[`a`b;4 2]
'assign
and using set:
q)set'[`a`b;4 2]
assigns to global, not local environment.
I believe you'll have difficulty saving local variables this way without a hacky solution and without knowing the reason for it needing to be local it's hard to produce a solution that could help. However, here's some suggestions:
if just you don't want global variables at the end of execution you could save these as global and remove them before exiting
if you don't want existing globals overwritten then I suggest saving these variables in a local dictionary instead with variable names as the key. eg.
(!). (`a`b;4 2)
You can access local variables using
q){c:3;?[(`$())!();();0b;`c]}[]
3
but the problem here is the assigning of values to local variables.
Related
I have a project consisting of multiple nested functions.
For debugging purpose I want to save all internal variables in one way or another, in order to display figures, replay parts of code etc...
I also want to keep this as transparent as possible regarding calculation time.
My first thought was to create a global variable, and store programmatically at the end of each function the inputs and outputs inside the variable as a structure :
globalVariable.nameOfParentfunction_NameOfFunction.nameInput1 = valueInput1;
globalVariable.nameOfParentfunction_NameOfFunction.nameInput2 = valueInput2;
...
globalVariable.nameOfParentfunction_NameOfFunction.nameOutput1 = valueOutput1;
...
Is it possible to use some kind of reflection to get the name and value of inputs/outputs without necessarily parse the file where the function is written?
I found a good but maybe outdated topic about parsing
How do I collect internal signals?
The simple solution is to use save, which will save all variables in the current workspace (the function’s context) to file.
If you want to keep the values in memory, not in a file, you can use names = who to get a list of all variables defined in the current workspace, then use val = eval(names{i}) to get the value of the variable called name{i}.
I would recommend putting all of that in a separate function, which you can call from any other function to store its variables, to avoid repeating code. This function would use evalin('caller',…) to get names and values of variables in the workspace of the calling function.
Note that using eval or evalin prevents MATLAB from optimizing code using its JIT. They also are dangerous to use, since they can execute arbitrary code, however in this case you control what is being executed so that is no a concern.
A while ago I was reviewing some legacy code, and I incurred in the following issue: the developer create many variables starting with a dot (like .variable1), syntax reserved to define namesspaces.
When quizzed about the use of that convention, he replied that essentially that was a way to create global variable within the scope of a function - what in Python you would achieve doing the following:
def define():
global a
a = 2
define()
print(a)
In q, that translated in something like this:
f1:{.b1:2;}
f2:{b1:2;}
f1[] / this creates a variable .b1, which you can use globally
f2[] / this creates a variable b1 within the scope of the function, not usable outside
While my preference would have been to create a global variable using a namespace (something like f1:{.my_namespace.b1:2;}), the code was doing its job without any issues.
The problem arises if I want to delete the global variable defined which starts with a dot (.b1 in the case just described), given that approaches like
delete .b1 from `.
do not seem to work. All the references I was able to find (like this) suggest that namespaces cannot be delete, which would imply these unproperly defined variable will stay there.
To be clear, the problem is not about how to delete variables from namespaces, but to delete those namespaces which are used as variables - if possible at all.
Any ideas?
Based on your question, you want to delete variables from a namespace. You can do this by running:
delete b1 from `.my_namespace
Which is also explained in the link you pasted.
What you can't do is actually delete the reference to my_namespace.
As a side note you can also set variables globally in the root namespace using the set keyword:
{`var set 2}[]
Which will let you avoid having to create single use namespaces.
Is there any way to define a variable in main function and use it in all sub-function.
I've tried to declare variables as global but it seems I should repeat it in all function again. I'm wonder what's the benefit of global variable at all!
use variable as global:
main program
global x
syms x
subfunc1
subfunc2
...
and
subfunc1
global x
and
subfunc2
global x
(maybe this format remind us to have global variable in function but it was better to cause error if we use same name of variable in function same as Matlab keywords)
I don't want to import the variable as all function argument and don't want to declare that variable in all function again and again.
any help would be appreciated.
If you really want to have access to the same variable, then there are only two ways I know of in Matlab:
nested functions(described by answer from #justthom8) and global variables. Other methods of getting data into functions exist, such as getappdata, guidata and (my personal favorite:) passing function arguments. However, these approaches make copies of variables.
Perhaps you should ask yourself why you want to avoid making copies of variables. If you are worried about performance, you should know that Matlab efficiently use variables as reference to data only, so you can safely send a variable in to a function (thereby copying the variable) without copying the actual data. its first after you modify the data inside of the function that the data is actually copied. All this is totally invisible to us, except as a possible drop in performance during alot of copying. This is called copy-on-write.
Global variables can be used to optimize Matlabs performance, by coding them in such a way as to avoid copying data, but that really requires knowing what you are doing, and it opens up for a whole lot of pitfalls, especially if your projects grow in size.
One thing you can do is define the other functions as subfunctions of the main function. Something like below
Both of the functions subFunc1 and subFunc2 should have access to data you define above it in mainFunc
function mainFunc()
variable1 = 'stuff';
variable2 = 5;
function subFunc1()
%do stuff
end
function subFunc2()
%do more stuff
end
end
Edit 1
Of course you can define global data in the mainFunc that gets used in the subfunctions, but I wouldn't recommend doing that since it can get changed in unexpected ways that you don't intend for to happen.
I want to do something like this: a program where at the beginning some data is initialized. Then I open other GUIs where I show some graphics from these data.
Is there any possible way to set some global variables for different GUIs? If not, how could I do it?
As long as you pass the handle of the first GUI to the second, you can access all the properties of GUI#1 from GUI#2 (and vice versa, since the GUI creation method returns the handle to GUI#2).
Alternatively, you can collect the data you want to visualize (as well as the handles of the GUIs) in a handle object, which means it is passed by reference and thus available everywhere.
Finally, you can, of course, create global variables - at the beginning of any function that would like to access these variables you have to declare them as global var1, var2, var3.
Is it possible to retrieve a local variable from a programme-function i've run in matlab? i.e. i want to retrieve a variable from the code, which is not appeared in the outputs.
Thanks in advance
The following describes code to add to the function itself to make the variable available outside the local scope. When you can't change the function, from the outside there is nothing to be done about changing the scope of course (which is intended, correct behaviour!!).
Dirty ways:
global variables
global t
t=2.468;
For scalars, strings, simple values: assign to variables in base workspace using evalin:
t=2.468;
evalin('base', ['var_in_base=' num2str(t) ';']);
Any other variable, use assignin:
A=magic(20);
assignin('base','A',A);
Proper way:
Inspect them during debugging
If you really want them outside the local scope, add them as output variable!!
Look at Declare function. You can access local variables if you return them as return values. If you do not, you can't access them from outside.
So in
function [mean,stdev] = stat(x)
n = length(x);
mean = sum(x)/n;
stdev = sqrt(sum((x-mean).^2/n));
You have access to mean and stdev but there is no way to access n.
I don't know matlab at all, but from programmer's logic
that seems improper and impossible without hacking the code.
That being said, through Google I saw this:
When you call a script from a function, the script uses the function workspace.
Like local functions, nested functions have their own workspaces. However, these workspaces are unique in two significant ways:
Nested functions can access and modify variables in the workspaces of the functions that contain them.
All of the variables in nested functions or the functions that contain them must be explicitly defined. That is, you cannot call a function or script that assigns values to variables unless those variables already exist in the function workspace.
Base and Function Workspace
Not sure if this helps you at all, but it may clarify some points