views:

120

answers:

3

I'll probably best explain this through code. I got something like this:

var object1 = function(){ 
  //do something 
}
var object2 = function(){
  //do something else
}

var objects = {
  'o1' : object1,
  'o2' : object2  
};

var actions = [];

function addAction( actionName ){
 var object = objects[actionName];
 actions.push( function(){ new object(); } );
}

So this code, saves a sequence of runtime-determined actions based on user input that are saved in an array.

addAction( "o1" );
addAction( "o2" );

If I want to replay that sequence I just do:

for( i in actions ){
  actions[i]();
}

and this will create two anonymous objects of type object1 and object2.

Now, I need somehow to serialize the actions[] array but I need each of the functions within it to retain it's scope. If I just cast the functions to strings I get:

"function(){ new object(); }"

and if I eval this string, then 'object' would be undefined. How would you do this ?

+1  A: 

I am a bit unclear on what scope you expect the function to have.

Simply pushing the function in

actions.push(objects[actionName]);

may have the effect you want...

larson4
+4  A: 

Why not keep the name of the action along with the function in an object, so that you can use that for serialisation:

function Action(name, func) {
   this.name = name;
   this.func = objects[name];
}

function addAction(actionName) {
   actions.push(new Action(actionName));
}

The code to run the functions would change slightly:

for (i in actions) actions[i].func();

To serialise the array you would just put the names in a string:

var s = '';
for (i in actions) {
   s += (s.length == 0 ? '' : ',') + actions[i].name;
}

Then to deserialise you just recreate the objects from the names:

var names = s.split(',');
for (i in names) {
   addAction(new Action(names[i]));
}
Guffa
+1  A: 

If you want to serialize your list of actions for playback later, you should modify your addAction function to just store the name of the action.

function addAction(actionName)
{
    actions.push(actionName);
}

And when you go to play back, you'd use

for(i in actions)
{
    objects[actions[i]]();
}

Since your action list is just strings, you should have no problem with the serialization.

Corey Ross