newbie wants to eval()

Kragen Sitaker kragen at dnaco.net
Sun Jul 1 07:39:35 EDT 2001


In article <3b3e655b$0$88181$2c3e98f8 at news.voyager.net>,
lynx <noone at nowhere.net> wrote:
>hmm. is there something inherently evil about exec that i should know
>about...?

exec and eval are an easy way to write code that works some of the time
and breaks in spectacular and completely unexpected ways when you get
unexpected input.

Their effect depends entirely on their arguments.  They can do anything
--- literally anything at all.  This makes it hard for you to determine
why your program is breaking.

Say you find that a variable named 'max_pool' is getting set to some
incorrect value and this is breaking your program.  Without 'exec' or
'eval' (or other similar, but less dangerous, things like setattr), you
can look in the scope of max_pool to see where max_pool gets set ---
only in statements that look like this:

	max_pool = <something>

There are probably only three or four of these, and you can probably
look at the <something> to see if it could possibly be evaluating to
the incorrect value you're seeing.  Probably one or two of them could,
so you put a print statement above them to see what's happening.
Voila, you found the bug.

Now, if, in addition to these three or four assignments, there are also
five or six places you're calling exec or eval, any one of those places
could be messing with max_pool.  Whether they are or not probably
depends on some data you computed earlier, or possibly read in from a
file or something.  Your problem may have gotten as much as three times
harder.

What's worse, it's probably hard to tell what's being assigned to
max_pool in your exec strings; you probably have to look at some stuff
that's being interpolated into a string with %, figure out what it
could evaluate to, and then look at the resulting expression and figure
out what *it* could evaluate to.  This extra level of indirection isn't
trivial for the smartest of us.

Also, as someone (Alex?) pointed out, not only can't you easily reason
about what your code is doing once you introduce exec or eval, neither
can the compiler, so it tends to produce slower code.

So use exec and eval only when it saves you pages of code, because the
price you pay is bigger than you think.

This advice applies to Perl and Tcl, too, and any other language that
gives you eval "string"; some of it applies to Lisp, but some probably
doesn't.
-- 
<kragen at pobox.com>       Kragen Sitaker     <http://www.pobox.com/~kragen/>
Perilous to all of us are the devices of an art deeper than we possess
ourselves.
       -- Gandalf the White [J.R.R. Tolkien, "The Two Towers", Bk 3, Ch. XI]




More information about the Python-list mailing list