below is a dump of data about how LiveEdit works and its limitations and some pretty wild demos to show it's power.
there is additional info in a thread (between peter and jjb that could be useful to surface. i can share with those interested.
Hi guys
To illustrate core concepts of LiveEdit and discuss how we can make LiveEdit more obvious for user, I hacked together a small demo site:
http://peter.rybin.spb.ru/liveedit_demo/index.html (couldn't find better place to host it quickly).
It shows what really happens when the script is edited live. The demo program has a simple Factory function, that produce an instance of nested function, which we should call "closure", since it binds variables from its outer scope:
( URL = http://peter.rybin.spb.ru/liveedit_demo/scripting.js )
var closure_list = [];
function Factory(p, q) {
return function() {
return "*" + p + "*";
}
}
The site allows you to create any number of the closures, specifying the value of p and q arguments. All created instances are saved in closure_list array and are always on display. Watch what happens to those closure instances.
Here's the demo steps:
- Optionally modify "p" argument, press "Create" button and watch how a nested function was created (you also can see what it evaluates to). Create more closures with other "p" and "q" values if you want.
- Open DevTools and in scripting.js do some "innocent" edits to the inner function. For example, change "*" to "$". Save.
- Back on the site, press "Refresh" button and see that the function text has been changed and that its result now is different. This is a trivial live editing.
- Optionally in DevTools watch closure_list global variable. It keeps our closure. Open its "function scope" node, and see that it only holds "p" and doesn't keep "q". That is where the problem stems from.
- In DevTools do "non-trivial" change to the inner function: add "q" value to return expression.
- Back on the site, press "Refresh" button and see that existing function(s) was not changed. Neither their result changed. That's because you commandeered "q" variable in the expression, but there is nowhere "q" actual value could be got from – only "p" value was saved in the function scope, as we observed in step #4.
- Optionally enter your signature string in "q" argument field and press "Create". See a new function with a new body text appears. Check that is also evaluates to the something with "q" value. Old instances remain unchanged.
- That is how LiveEdit works. If you patch a function to start using a new variable from outside, you cannot have it with function instance that is already around, because it doesn't have the variable value. The variable value is either bound or released at the instantiation moment, no later. All already created function instances will remain unpatched. Only newly created function instances will get a new body text.
- What was meant to be a plain function, now gets 2 versions. Since the demo keeps all instances, it's on display how some of them have old text, and some of them have a new text.
- Since every function belongs to the script, the script itself must be split into 2 versions. Naturally, you must be able to step through the function and debugger must bring up the corresponding script text. Since there are 2 versions of the function, there must be 2 versions of the script.
- LiveEdit V8 engine creates the required script copy. However, DevTools does not currently allow it to UI, which is probably a bug: you are going to fail to step into such function, because it lacks a script. However, the function is seemingly alright in other means, for example you can call it or see its text.
Sorry for a long story. I understand it was complex. I hope this can help us understand how we can try to make LiveEdit more clear for the user – I guess first we should make it clear for ourselves. For example, once I have written it, we could implement a scenario: only "innocent" changes go smoothly. In the complex scenario we can pop up a dialog: «Hey, you are doing a complicated thing. Somewhere in your edits you started to use variable "q" – a thing we were not prepared for. For this fault you will get your script split. Ok with that?»
Peter