Eval on multi-line strings - no return value?

23 visualizzazioni (ultimi 30 giorni)
Mark
Mark il 22 Lug 2014
Risposto: raym il 13 Lug 2018
I'm using R2011b. I'm trying to evaluate a string, potentially with multiple lines, and obtain a final return value.
For example:
sprintf('a=25\nif (a == 30)\n a = 75;\nelse\n a =42\nend\n37')
result = eval(ans)
Produces: "Error: The expression to the left of the equals sign is not a valid target for an assignment."
For clarity, the sprintf result is:
ans =
a=25
if (a == 30)
a = 75;
else
a =42
end
37
The error is confusing to me, as I would expect the last line of this block to return a value of 37. For example:
sprintf('37')
result = eval(ans)
Creates a result variable with value of 37, as I would expect.
Further troubling me is the fact that:
sprintf('a=25\nif (a == 30)\n a = 75;\nelse\n a =42\nend\n37')
eval(ans)
Executes appropriately, and even updates the ans variable to 37.. which to me implies that MATLAB kind of knows there is a return value for this code block. Thus this adds to my confusion as to why I can't override the assignment to ans with a new variable... it's like, it's too late if you are evaling a multi-line block, but not a single line expression.
Can anyone explain the fault in my expectations here?
thanks!

Risposta accettata

Joseph Cheng
Joseph Cheng il 22 Lug 2014
to expand it a bit more. what is going on with your result = eval(string) is exactly how it is written.
you're setting everything within the string into the result which doesn't compute. so in essence you're typing (which won't work)
>> result = a=25,if (a == 30),a = 75;,else,a =42,end,37
which doesn't get you result = 37
What you could do just like you did with your fprintf statement
just do:
sprintf('a=25\nif (a == 30)\n a = 75;\nelse\n a =42\nend\n37')
eval(ans)
result = ans
  3 Commenti
Joseph Cheng
Joseph Cheng il 23 Lug 2014
again, think of eval as what you can type in the command window. if you type that out its like x = 1;
when you type in x in the command window you don't get ans = x;
Joseph Cheng
Joseph Cheng il 23 Lug 2014
Modificato: Joseph Cheng il 23 Lug 2014
The better question is what you attempting to do with the eval? What is the reasoning behind why you are performing this using eval instead of any other method?

Accedi per commentare.

Più risposte (3)

Joe V
Joe V il 20 Ago 2014
I hope I can add some further insight to what others have said. The main reason eval isn't working the way you expect is that you're evaluating a statement, which can't have a return value (as opposed to an expression, which can have a return value). The eval function can evaluate either but only returns values from expressions, not statements.
MATLAB makes a strong distinction between statements and expressions. Statements are "things you do" -- lines that end in a semicolon, or like Joseph Cheng said, "what you can type in the command window." Examples include assignments, if statements, and other things. Expressions, on the other hand, are bits of code that have a value, like 1+2 or sin(2*pi*(0:0.01:1)). Expressions can be used inside of other expressions.
You can use an expression by itself as a statement, in which case it's equivalent to the statement ans = expression. However, you can't use a statement as an expression. In other words, statements don't have a result or a return value.
The eval function makes the same distinction. If you evaluate an expression, it can produce results, like a = eval('1+2'). But if you evaluate a statement or a sequence of statements, as you are doing, eval can't return any results, since statements don't have results. Another example: a = eval('37') works, since 37 can be interpreted as an expression, but a = eval('37;') throws an error, since the semicolon forces eval to interpret the string as a statement, and a statement can't have a return value.
The reason that the statement
eval('if a == 30, a = 75; else a = 42; end; 37')
prints out ans = 37 is not that eval is returning a result. The ans printout actually comes from inside the eval. You've got a sequence of statements, and the final statement is 37, which is equivalent to the statement ans = 37. The last statement doesn't end in a semicolon, so the value of ans is printed out. To prove that the printout is coming from inside the eval, try doing this (be careful to note the semicolon placement):
eval('if a == 30, a = 75; else a = 42; end; 37;')
Nothing prints out, because the eval has no result (no return value). But if you try this (note semicolons again):
eval('if a == 30, a = 75; else a = 42; end; 37');
then MATLAB still prints out ans = 37. The outer semicolon silences the eval (which has no result anyway), but the result from the 37 is still printed.
One more point: You asked "when and why functions are considered to have return values." The eval string is not considered a function (even though it might look that way when you're eval'ing an expression and using the results). But to answer your question directly: If you use a function in an assignment, the function must have at least as many outputs as the assignment needs, e.g. [maxval,idx] = max([3 4 5]). If you use a function in an expression, the function must have at least one output and only the first output is used, e.g. a = 1 + disp('hi') fails, and a = 2 + max([3 4 5]) succeeds but ignores the extra outputs from max. If you use a function call as a statement by itself, it doesn't need to provide any outputs, but if it does, the first output is assigned to ans and the other outputs are ignored.

Azzi Abdelmalek
Azzi Abdelmalek il 22 Lug 2014
str='a=12'
eval(str) % When you run this line, the number 12 will be assigned to 12
str='a=12'
result=eval(str) % eval(str), like above, will assign 12 to a, not to result, that's why this line of code is not understood by Matlab.
  3 Commenti
Azzi Abdelmalek
Azzi Abdelmalek il 22 Lug 2014
If you want assign 37 to result just write
result=37
or
eval('result=37')
eval(expression) does not return any value, it allows to evaluate an expression.
Mark
Mark il 23 Lug 2014
The point is that I have one or more, potentially unknown, lines matlab code in a string that I want to evaluate and report a return value from if appropriate.
I'm sorry if it wasn't clear, but this question isn't about assigning variables. It's about extracting results of string evaluation and understanding when and why functions are considered to have return values.
eval(expression) does sometimes return a value, as I illustrated in my original post. To reiterate, I can say:
result = eval('1+2')
which will store a value of 3 into result. To me, that means that eval returned something, but maybe I have some fundamental misunderstanding here?

Accedi per commentare.


raym
raym il 13 Lug 2018
Great! I found a new way to eval a block of code stored in text file.

Categorie

Scopri di più su Entering Commands in Help Center e File Exchange

Tag

Community Treasure Hunt

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

Start Hunting!

Translated by