Does justifiable use of EVAL exist?

4 visualizzazioni (ultimi 30 giorni)
per isakson
per isakson il 18 Feb 2017
Commentato: Sean de Wolski il 31 Ago 2017
Here at Matlab Answers we often answer and discuss questions related to dynamic names of variables and EVAL, here short for the functions, eval, evalin and assignin. All(?) of those engaged agree that EVAL should be avoided. And there are good reasons, see e.g.
However , EVAL exists in Matlab and it's used even by The MathWorks. I searched for eval and evalc in Matlab, R2016a, and found 272 occurances in 136 files. (Tool: FileLocator Lite , Search string: |\Wevalc{0,1}\(| &nbsp in &nbsp matbalroot\toolbox\matlab\*.m &nbsp and subfolders.) Nearly 7000 files were searched. This indicates that EVAL is used in 2% of the files.
Does justifiable use of EVAL exist? If so, which are the criteria for a justifiable use of EVAL?
  • The practicability of an alternate EVAL-free code. If one can come up with an EVAL-free code, one should not consider using EVAL! Does the cost of the EVAL-free alternative matter?
  • The context is important. It's a huge difference between a through-away-code used in an experiment and a function in a Matlab toolbox.
  • The problem must be worth solving. Many EVAL-related question are on attempted solutions to solve problems caused by poor design decisions rather than on the real problem.
Here are some candidates of justifiable use of EVAL
  • db2b, debug to base, is a function which I use interactively to save variables from a function workspace to the base workspace. It's based on assignin('base',...). There are a handful of similar functions in the File Exchange.
  • I used sam=mlint('-calls',filespec) in a couple of functions, one of which I had uploaded to File Exchange. This stopped working in a recent release of Matlab. Replacing mlint with checkcode didn't help. The quick solution was &nbsp str=evalc('mlint(''-calls'',filespec)');. Yes, '-calls' isn't documented.
  • Years ago I made an experimental GUI to visualize time series. I wanted to explore whether it was useful to let the user do some math on the series. I provided an edit box and used EVAL to evaluate the Matlab-code, which the user entered. The experiment was quickly done and useful.
  • The other day I answered a question on " ... cycle through ... workspace variables ... convert ... to single". I didn't see a solution without EVAL. I tried to show that one shall encapsulate the ugly code in a function, give it a good name and guard against unwanted side effect with thorough tests. Whether the problem was worth solving I don't really know.
&nbsp
Here add to the cases presented in the documentation Alternatives to the eval Function
  2 Commenti
Stephen23
Stephen23 il 19 Feb 2017
Modificato: Stephen23 il 20 Feb 2017
The first paragraph of the question is highly significant: clearly this question excludes those beginners who wish to use eval to generate dynamic variable names. Note that both Jan Simon's and my thread are specifically targeted at dynamic variable names (as the thread titles clearly state), and not at eval for all possible use-cases. For the case of dynamic variable names it is understood that there are much better solutions available (e.g. indexing in particular).
I think there is a very zen answer to the question though: "Know the rules well, so you can break them effectively". When someone really understands eval (JIT and all), then they are ready to use it. I suspect they won't be using it much though!
@per isakson: I added Jan Simon's thread/question to your list.
Adam
Adam il 20 Feb 2017
Well, I haven't searched myself, but if those 272 occurrences occur in MathWorks code I assume they would give some examples of when it may be considered acceptable. Personally I have (purposely) never learned about eval to understand how to use it and have never had a situation that calls for it, but I doubt those 272 case are just MathWorks people being sloppy.
That said, code for builtin functionality sometimes needs to do things that our own code should never need to consider doing.

Accedi per commentare.

Risposte (2)

Walter Roberson
Walter Roberson il 19 Feb 2017
Modificato: Walter Roberson il 19 Feb 2017
  • If you are writing a debugger for MATLAB in MATLAB, then you probably need eval(). Writing to a file and running the file is not exactly the same.
  • I consider evalin() to be eval(). I am not sure it can be escaped for some parts of the Symbolic Toolbox; some other third-party toolboxes make good use of it as well. It cannot be avoided for From Workspace blocks in Simulink.
  • using MATLAB as an "engine" from C / C++ / Java etc. requires an implicit eval()
Also, there are a lot of cases in which it is necessary to allow the user to enter an expression as a string. It is not strictly necessary to eval() those strings, but the reality is that writing a parser is a real Lebanese/Greek flatbread.
  3 Commenti
Adam
Adam il 27 Feb 2017
I tend to shy away from str2fun after using it once where it seemed neat, going from a popup list of wavelet types to the equivalent function calls rather than a big switch statement, but then I realised that for building deployed software this is a real pain since of course it doesn't pick up the function dependencies for all those functions.
Maybe had I not been needing to build the software it might have been fine, but when dependency checking is vital or laborious manual adding of all the extra files, assuming you can even remember them it was not a good solution.
Walter Roberson
Walter Roberson il 27 Feb 2017
Hmmm...
Okay, suppose you want the user to be able to supply an expression (e.g., to plot, to integrate.) You do checks and everything looks okay. Maybe even you do some security checks to be sure that the function named have not been redirected.
Now, you could potentially have written an expression parser that breaks down the expression string into a parse tree of data, and you might have routines to execute the parse tree using only operations you supply and standard functions, never calling any user-supplied function. So you might technically be able to analyze the string and build up appropriate flow of control in the mini-language you have designed to communicate with the user.
But... How do you make that execution efficient ? Without using eval() or str2fun() ? Can you do that efficiently without dropping into mex to run the parse tree?
Efficiency might be pretty meaningful, since you might have McBoaty-Face loads of process, such as if you are integrating or doing ode*() or a minimization.
In the case of expressions, one cheat to not directly use eval() or str2fun() is to use the symbolic toolbox to construct a function handle. The symbolic toolbox of course uses str2fun() itself.

Accedi per commentare.


Jan
Jan il 20 Feb 2017
The fact, that 2% of Matlab's toolbox functions contain an eval does not mean, that this is a good strategy.
I've used eval once only in my programs: For an automatic test, I had to call a large program hundreds of times and in each run ten thousands of lines are written to the command window. This takes some time, I assume by updating the buffers or scrolling. In addition the output is too large to be read by a human, most of all not on the fly. Encapsulating the calls to the function in evalc() reduces the runtime significantly, as far as I remember by 20%.
But for productive use, the output to the command window is essential.
  3 Commenti
Jan
Jan il 31 Ago 2017
In Matlab 5.3 (perhaps 6.0 also) getfield was implemented with eval. Therefore the field name could contain dots to access subfields. This was useful but slow and undocumented.
It is bold to assume that users of a program are not evil. You find too many examples for exploited security holes to know, that a user can find a way to inject jun like "a; system('format D:')" as field name, and similar to SQL injections on web sites, eval can be used to influence a system in an unwanted way.
Of course the old getfield implementation could be made secure: Simply check at first, if the argument is a valid Matlab symbol without any special characters. But this was not done.
It is clear that eval can solve problems and therefore it will not be removed. But it can cause more problems also. eval is an invitation for security leaks.
Sean de Wolski
Sean de Wolski il 31 Ago 2017
I've found evalc to be necessary in user interfaces I need to deploy in order to get information back to the user. For example with: tf.
H = tf(Numerator,Denominator,'InputName','current',...
'OutputName',{'torque' 'ang. velocity'},...
'Variable','p')
H =
From input "current" to output...
p + 1
torque: -------------
p^2 + 2 p + 2
1
ang. velocity: -
p
Continuous-time transfer function.
Also this question:

Accedi per commentare.

Categorie

Scopri di più su Variables in Help Center e File Exchange

Prodotti

Community Treasure Hunt

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

Start Hunting!

Translated by