views:

127

answers:

5

I'm currently developing a tutorial site for teaching the fundamentals of Web development (HTML, CSS, and JavaScript, for starters). I'd like a setup where I could give in-depth coverage of all sorts of topics and then provide a basic sandbox environment where the user could write code which solves the question asked at the end of each tutorial section.

For example, if I'd covered multiplication in a previous tutorial, and the user had just finished a lesson on functions being capable of returning values, I might request that they submit a function which returns the product of two parameters.

Is this not the perfect instance in which using dynamic function creation would be considered a good idea? Let's look at an example.

<script>
function check()
 {
eval('var f = ' + document.getElementById('user_code').value);
if (f(5, 10) == 50)
 {
// user properly wrote a function which
// returned the product of its parameters
 }
 }
</script>

Is this at all a bad idea? If so, please explain.

+1  A: 

Sounds like you want to remake Firebug or even the new Developer Tools in IE8. Due to that, I'm going to have to say there is never a useful case. Not to mention the possibilities of script injection if this site goes public.

geowa4
Not helpful in the slightest, mate...
Hexagon Theory
You're trying to reinvent the wheel. Would you rather I just said no, since what you're trying to accomplish has been done?
geowa4
You most certainly didn't read my question properly; I clearly stated that I was considering using this method on a Web site for a precise reason. Why in the world would I be looking for a Firefox-only tool that doesn't even do what I was inquiring about in the first place?
Hexagon Theory
You can definitely write functions in Firebug... Oh and you can in IE8 too.
geowa4
one last thing. firebug isn't FF only.
geowa4
+1  A: 

This sounds like it could work. However, the biggest challenge in your environment might be error handling. Students will surely make all sorts of errors:

  • Compile time errors, that will be detected in eval()
  • Run time errors, that will be detected when you call the function
  • Undetectable run time errors, such as an infinite loop or a stack overflow

A more elaborate approach might parse the entered Javascript into a parse tree representation, then compare it to an expected parse tree. If it does not match, then point out what might be wrong and have the student try again. If it does match, then you can eval() and call the function, knowing that it will do what you expect.

Implementing a lexer and parser for Javascript in Javascript would be challenging but certainly not impossible.

Greg Hewgill
+1  A: 

Should work as long as you're operating this in a closed environment. Eval opens you up to code injection attacks so I wouldn't put this on a publicly accessible web site, but if it's completely contained within your class room you should be ok.

Jared
+1  A: 

The code would work, but what if there is an error both syntactically or otherwise ? Perhaps use a try block to catch any error and display it to the user would help things a little...

Not sure if this helps.

Jobo
+1  A: 

In your case, I feel that there is nothing wrong with this. Alternatively you can run the code by using new Function() to build stuff first and then run it. In theory, this would separate the stages of "compiling" and executing. However eval will check the code first and throw errors anyway:

var usercode = document.getElementById('user_code').value;
try {

  var f = new Function( 'a','b','return (' + usercode + ')(a,b);' );
  if ( f( 5, 10 ) ) {
    // user properly wrote a function which
    // returned the product of its parameters
  }
  else {
    // user wrote code that ran but produced incorrect results
  }

}
catch ( ex ) {
  // user wrote something really bad
}

The problem with doing things in this manner is that the exceptions thrown may be nonsensical. "foo;;=bar" will report a "missing ) in parenthetical" error while eval will throw a propper syntax error. You could bypass this by (regexp) grabbing the parameters and body from the user code first and then building it. But then, how would this be any better than an eval?

I think that your real problem will be helping users avoid the pitfalls of implicit globals. How are you going to help users avoid writing code that only works the second time it runs because a global was set the first time? Will you not need to implement a clean sandbox every run? I would take a look at how jsbin.com, firebug and similar tools handle these things.

My feeling is that you should go with eval for now and change it for more elaborate stuff later if the need arrises.

Borgar