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 Commenti

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 il 29 Gen 2014
Modificato: G A il 29 Gen 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.:)

Accedi per commentare.

 Risposta accettata

function myfun(varargin)
varargin{:}

17 Commenti

Fancier:
function myfun(varargin)
for i=1:nargin
disp([inputname(i) '=' num2str(varargin{i}) ]);
end
Thanks! I tried this approach before but without {:} .
G A
G A il 28 Gen 2014
Modificato: G A il 28 Gen 2014
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 il 29 Gen 2014
Modificato: G A il 29 Gen 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 ?
Matt J
Matt J il 29 Gen 2014
Modificato: Matt J il 29 Gen 2014
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 il 29 Gen 2014
Modificato: G A il 29 Gen 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 il 31 Gen 2014
Modificato: G A il 31 Gen 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?
Matt J
Matt J il 31 Gen 2014
Modificato: Matt J il 31 Gen 2014
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 il 31 Gen 2014
Modificato: G A il 31 Gen 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'}...

Accedi per commentare.

Più risposte (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 Commenti

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!

Accedi per commentare.

Categorie

Richiesto:

G A
il 28 Gen 2014

Modificato:

G A
il 31 Gen 2014

Community Treasure Hunt

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

Start Hunting!

Translated by