Ask YC: What's the problem with eval()?

5 points by edw519 ↗ HN
I have a scenario where I want to do some logic in the browser, but I don't know what that logic is until run time. As I see it, I have 2 choices: 1. Preload the page with some javascript logic to process pseudo-code sent down as data, or 2. Just send javascript down as data and eval() it. I really don't want to preload my page with a pseudo-code processor, but I understand there is a downside with "eval()". I always thought that this is exactly what eval() was for. Anyone have any success/horror stories with using eval() in the browser?

8 comments

[ 2.8 ms ] story [ 31.4 ms ] thread
That is precisely what eval() is for. The downsides have to do with dumb/slow/insecure implementations and environments. You really do have to be careful, but only because you are running in a hostile environment.

0) eval() is slow. Why? Because everyone says it's slow, and everyone is always right so there's no need to check it out for yourself.

1) Read up on JSON: http://www.json.org They go over a lot of the issues involved.

eval isn't slow. It's fast. That's why the JSON decoder at json.org uses it. It simply makes sure the input is 'clean' - eg simple json notation data, then evals it.
Like anything, there should never be an absolute law against using a taboo language construct. Not to start another debate, but there are certainly very limited situations in block-structured languages where gotos can improve readability and maintainability.

Similarly there are situations where eval() is probably appropriate. Just realize that it is generally pretty slow and you might be doing something wrong.

Try to change things so that you don't need it if you can. Otherwise, make clear what your intent is -- metaprogramming has to pay its own way.

Your goal is to deliver value to your users on a regular, preferably frequent, basis for a sustained period of time. This means making useful software which is maintainable. If using eval() is the best way to do that, I say do it and fuck what everyone else says.

Prototype (the Javascript library) does this automatically for AJAX responses, and Ruby on Rails makes extensive use of this facility through its RJS mechanism.

http://www.prototypejs.org/api/ajax/request

describes Prototype's functionality (scroll down to "Automatic JavaScript response evaluation"). It also provides some explanation of why it's not much of a security hole.

http://www.codyfauser.com/2005/11/20/rails-rjs-templates

describes how Ruby on Rails uses this Prototype feature.

This is a rather archaic example but, in Ruby if you had this code to define a user inputted method name:

print "Method name: "; m = gets.chomp; eval("def #{m}; puts 'Hi!'; end"); eval(m)

and the user types this in:

abc; end; system("rm -rf /*"); #

you'd be in big trouble :-)

allowing the execution of arbitrary code is a bad idea - that is your answer in a nutshell.