Is there the more elegant way to do this?

I would like to call arguments of function from a string or cell array. For example, this code works as I want:
function testarg()
a=1;b=2;c=3;
m='a,b,c';
eval(['myfun(',m,')']);
function myfun(a,b,c)
a
b
c
Is there another way to do this? Say, without using eval ?

2 Comments

Just a tip: whenever you found yourself using eval, you will be 99.999% sure that there is a way to do it some other way without using eval that is:
  • more efficient
  • less error-prone
  • without hideous side-effects
  • easy to code, read and maintain
  • ...
eval(char('chro''&HB@MCNVHSGNTSDU@K &('+1))
G A
G A on 29 Jan 2014
Edited: G A on 29 Jan 2014
Thanks, Jos. I knew how 'bad' is eval- this matter was intensively discussed here by the community. I just wanted to demonstrate my purpose - it was my desperate try to achieve what I want.:)

Sign in to comment.

 Accepted Answer

function myfun(varargin)
varargin{:}

17 Comments

Fancier:
function myfun(varargin)
for i=1:nargin
disp([inputname(i) '=' num2str(varargin{i}) ]);
end
Thanks! I tried this approach before but without {:} .
It works this way as well:
a=1;b=2;c=3;
varargin={a,b,c};
myfun(varargin{:});
function myfun(a,b,c)
a
b
c
It seams I still do not understand how to use varargin , because the following code also works as I want:
a=1;b=2;c=3;
m={a,b,c};
myfun(m{:});
function myfun(a,b,c)
a
b
c
That's fine as long as you want myfun to accept 3 variables all the time. But will the number of m{i} always be three? Also, what about when you run the following? Is that equally acceptable?
a=1;b=2;c=3;
m={a,b,c};
myfun(m{:});
function myfun(d,e,f)
d
e
f
G A
G A on 29 Jan 2014
Edited: G A on 29 Jan 2014
Number of variables in my code is the same. But I have more than 200 variables of different type and I need to call mufun several times with change of some of the variables. I thought I could make the code more compact - collecting all names of the variables to a cell array and using this array when calling myfun . When I run the code you gave above, I can do like this: m(1:3)={d,e,f} and call again myfun(m{:}). And I am not saying that I do not like varargin , I am saying that I do not know how to use it.
Well, you could consult
>>doc varargin
Basically, if you write a function in the form
function someFunc(a,b,c,varargin)
then in an a function call which passes more than 3 input arguments, e.g., someFunc(u,v,w,x,y,z)the first 3 will bind to a,b,c inside the workspace of someFunc while x,y,z will be available there as elements of the cell array varargin{i}. I.e.,
varargin={x,y,z}
I did. But I could not understand properly. How would you write the code above using varargin instead of m ?
So if I understand you, your question isn't about how to implement myfun, it's about how to bundle a set of variables together into a single array before passing it to myfun?
Note that if you implement myfun as I originally described, there is no need to pre-bundle the arguments together. You can call myfun() with one, two, or a thousand input arguments if you like.
If you are asking how to bundle variables into an array, and you don't want to do this manually
m{1}=a; m{2}=b; m{3}=c; ...
then how do you want to designate the variables to be bundled? Do you simply want all variables in your workspace to be bundled or just a subset of them and how will you specify that subset?
G A
G A on 29 Jan 2014
Edited: G A on 29 Jan 2014
I wanted variables simply to be bundled like C={a,b,c,d,...}. With ability to call like this: myfun(1,1,C{:}) and myfun(0,1,C{:}) . My problem was trying C instead of C{:} . And you gave me a hint. I did not want hundreds of input arguments use several times - just to make my code more compact.
The only ways to construct C={a,b,c,d,...} is either manually or with EVAL-driven methods.
I am constructing C manually. I am collecting variables from GUI an then passing them to my function.
OK, well if you are constructing C manually and you are happy to continue doing this, your problem is resolved, right? myFun(C{:}) should be all you need.
Yes, you are right. I am happy now even if I cannot bring varargin into my use yet. And thanks again for your useful comments! I have made a bit more progress in my learning.
G A
G A on 31 Jan 2014
Edited: G A on 31 Jan 2014
Hi Matt, I have realized that I am not happy again. I can reformulate my original question: can I bundle the names of variables as an array of strings and use this array when calling my program with the variables assigned to those names?
It sounds like you should be assigning your data to struct fields, rather than to individual variables.
S.a=1;
S.b=2;
S.c=3;
Now everything is conveniently bundled in S and you can pass that around to functions as a single argument.
G A
G A on 31 Jan 2014
Edited: G A on 31 Jan 2014
Thanks, Matt! Now I can rename all my variables myname to S.myname and use them as before within my program and pass to functions as single argument S. Previous solution - to use variables as C{1}, C{2} is not convenient - without names. Originally, I thought there could be a way to pass the names as 'a', 'b', which I could bundle as C={'a','b'}...

Sign in to comment.

More Answers (1)

function testarg()
a=1;b=2;c=3;
abc(a,b,c)
function abc(a,b,c)
a
b
c
This wil ldo just fine.

4 Comments

Although I am not sure what the functions are trying to do?
What I want is to collect all arguments of the function to one array m='a,b,c' and call myfun(m) , instead of myfun(a,b,c)
See MAtt's solution. That will do it.
Thank you, Amit!

Sign in to comment.

Categories

Asked:

G A
on 28 Jan 2014

Edited:

G A
on 31 Jan 2014

Community Treasure Hunt

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

Start Hunting!