Why is `eval` worse than` str2func` to evaluate a function from a string?

I have already shown that performance is str2funcbetter , but I got a lot of comments stating that there are more fundamental reasons not to use it eval. What are the main reasons related to evaland not related to str2funcin the following situation:

f='a^x+exp(b)+sin(c*x)+d'
  • eval:

    y = eval(f)
    

    or (suggested by rahnema1)

    fHandle = eval(['@(x, a, b, c, d) ' f]);
    y = fHandle(x, a, b, c, d);
    
  • str2func:

    fHandle = str2func(['@(x, a, b, c, d) ' f]);
    y = fHandle(x, a, b, c, d);
    

Why is the first option worse than the second, with the exception of performance reasons ?

Notes

  • Please note that I know that it is recommended to avoid both methods if possible.

  • Note that I assign the output to a evalvariable that avoids the execution of a lot of complex code.

+2
4

, , .


. , script, , , ( ). .

  • str2func , , , , . ", , " ...

    % Not assigning an output variable
    % STR2FUNC: You've harmlessly assigned ans to some junk function
    str2func('delete test.txt') 
    % EVAL: You've just deleted your super important document
    eval('delete test.txt')     
    
    % Assigning an output variable
    % STR2FUNC: You get a clear warning that this is not a valid function
    f = str2func('delete test.txt') 
    % EVAL: You can a non-descript error "Unexpected MATLAB expression"
    f = eval('delete test.txt')
    
  • , str2func . " str2func eval".

    [ ]
    , .

    [ str2func eval]
    str2func , , [...]. eval .


, , , eval str2func, , .

+7

eval. , . , , .

:

>> ls TMPFILE
Error using ls (line 35)
ls: cannot access 'TMPFILE': No such file or directory

>> y = eval('system(''touch TMPFILE'')');
>> y

y =

     0

>> ls TMPFILE
TMPFILE

touch - unix; . rm -rf ~ .

str2func:

>> y = str2func('system(''touch TMPFILE2'')');
Warning: The input to STR2FUNC "system('touch TMPFILE2')" is not a valid function name. This will generate an error in a future release. 
>> ls TMPFILE2
Error using ls (line 35)
ls: cannot access 'TMPFILE2': No such file or directory

>> y

y =

  function_handle with value:

    @system('touch TMPFILE2')

>> y()
Undefined function or variable 'system('touch TMPFILE2')'.

: eval , - , eval , . , str2num:

>> x = str2num('[system(''touch TMPFILE3'')]')        

x =

     0

>> ls TMPFILE3
TMPFILE3

, eval, , , , . , : str2double str2num str2func eval ( , str2func ).

+8

-, ( x100 ) , -.

. " eval ?". , , str2func, . , eval, , , eval, .

eval , ( , , ). , , eval, , . , eval , . rm -rf, . , . , , .

? , eval. , .

-. eval . , , .

,

model.solve_algorithm=eval(['default(',[ class(input3) ],')']);
result=eval(model.solve_algorithm);

? ? , , . , , . - , .

TL;DR: , eval, :

  • , ,
  • , , /.
+8

TL; DR - eval , str2func - . "" , , .


" eval ", MATLAB, :

:

function out = q46213509
  f='a^x+exp(b)+sin(c*x)+d';
  fHandle = {eval(['@(x, a, b, c, d) ' f]), str2func(['@(x, a, b, c, d) ' f])};
  out = [fHandle{1}(1,2,3,4,5) fHandle{2}(1,2,3,4,5)];
end

function e = exp(x)
  e = x.^0./factorial(0) - x.^1./factorial(1) + x.^2./factorial(2); % Error is deliberate
end

, :

ans =

    8.7432   26.3287

If you work with classes, and you define your own operators , this can get out of hand ... Let's say someone decided to add a file to the MATLAB path and conveniently give it the name of any function that you are using, or overloaded operator (i.e. mpower.m)

function out = mpower(varargin)
  % This function disregards all inputs and prints info about the calling workspace.
  disp(struct2cell(evalin('caller','whos')));
end

Although in some cases MATLAB protects against overriding built-in functions, I'm sure the scenario described above can be a bit confusing str2func...

+8
source

Source: https://habr.com/ru/post/1685547/


All Articles