Control flow within the eval function in Matlab

If I include continue

commands as a parameter eval()

, it doesn't work as expected. For example, when executing the following code:

listParam = {'a','b','c'};
a = 17;
b = NaN;
c = 4;

for ii=1:numel(listParam),
    eval(['if isnan(',listParam{ii},'), continue; end']);
    disp(['The parameter ', listParam{ii}, ' is not a NaN.']);
end

      

It gives an error message:

Error: A CONTINUE may only be used within a FOR or WHILE loop.

      

Does anyone know why?

Note. I know I should be avoiding eval()

, and the previous example could be refactored into a much better encoding; but I found strange behavior and I am curious what is going on.

+3


source to share


2 answers


The expression you pass to eval

must be a valid matlab expression on it, any surrounding code is not considered. This means that everyone continue

must be surrounded by a noose. Either put the environment for

within your eval, or put it continue

outside.



+3


source


As @Daniel pointed out, the eval

script is called while it is not directly controlled by the outline for

. You may think that it is: continue

in eval

will move the program counter in the beginning of the code inside eval

, but not in the loop for

; this will of course fail as Matlab doesn't allow line jumping.

A continue

can be displayed directly inside the loop for

or while

. However, you can hack the code like this:

for ii=1:numel(listParam),
    eval(['if isnan(',listParam{ii},'), x=1; else, x=0; end']);
    if x
        continue;
    end
    disp(['The parameter ', listParam{ii}, ' is not a NaN.']);
end

      

Strange, x

appears on the script stack. However, this is far from good code. Never use this method.


Edit: about the "control" area eval

.



I'm not talking about variable scope / workspace eval

. Hints can be found in several docs such as this and this . In short, it eval

uses the "current" workspace.

However, I found the following interesting things:

  • Executing continue

    directly ineval

    for ii = 1:2
        eval('continue')
        ii+10
    end
    
          

    It just fails as shown in the question. Error Error: A CONTINUE may only be used within a FOR or WHILE loop.

    , which means it cannot find any loop (loop ) continue

    inside .eval

    for

  • Calling a separate script in a loop for

    for ii = 1:2
        foo
        ii+10
    end
    
          

    and the script foo.m

    is

    ii
    continue
    
          

    First of all, foo.m

    Mlint gives a red line warning, which usually indicates an error that could stop the code from running by indicating that CONTINUE is only valid in a FOR or WHILE loop

    . But pressing F5 foo.m

    doesn't cause any problems - in fact, running one continue

    anywhere doesn't crash the code.

    Running the main script gives the output

    ii =
         1
    ii =
         2
    >> 
    
          

    .... so what is foo.m

    catching the loop for

    ?

  • eval('foo')

    - I really don't understand Matlab

    for ii = 1:2
        eval('foo')
        ii+10
    end
    
          

    The result surprised me a little.

    ii =
         1
    ans =
        11
    ii =
         2
    ans =
        12
    >> 
    
          

Thought: eval

Runs code in an independent control flow, but shares its workspace with the current one. It is (something, but not quite) like an isolated world model in which (here in Matlab) different pieces of code can interact with the same set of variables, but cannot interact with each other in the sense of control flow.

Unfortunately, I have not been able to find any existing resources as a link to prove this idea.

This does not change my mind: try to avoid using it anyway eval

.

+2


source







All Articles