new Script object instead of eval

Hi,

Does someone have an example how to fire a method (text of the method is in a text-area) by using a new Script object??

I saw this someone doing on Servoy World in Boston.

Would love to see some examples.

Hi Harjo,

I must have been in the bar when this was going on…

Care to expand on what this new Script object is ?

Cheers
Harry

Like this:

var simpleScript = new Script('application.output("Do something");');
// Fire the script
simpleScript();

// 
// bunch of other code
// 

// And reuse
simpleScript();

Hi Robert,

Thanks for the info

Cheers
HArry

This looks really useful.
Is it available in 3.0 or 3.1?

It is available in 2.2.x. and up. Might also work in earlier versions. I dunno.

Here’s another possibility:

var simpleScript = 'application.output("Do something")';
// Fire the script
eval(simpleScript);

//
// bunch of other code
//

// And reuse
eval(simpleScript);

Only difference is with eval you keep compiling the script everytime you execute it.
With the new Script() approach you only compile it once.

Hi Robert

Thanks for the tip! I am not sure what you mean by compiling? I thought JavaScript is only interpreted, or are there compile options?

Best regards, Robert

ROCLASI:
Only difference is with eval you keep compiling the script everytime you execute it.
With the new Script() approach you only compile it once.

Hi Robert,

To be honest I am not exactly sure what it does. May it be compiling or syntax checking.
I believe it is transformed into some sort of byte code. I bet one of the Servoyans can tell more.
In any case using eval() you end up with a delay before executing.

Hi Robert

As far as I understood, JavaScript is an interpreted language. May be some day there will be as in Java a HotSpot compiling (option), but I never heard of such a thing for JavaScript.
I agree that eval is slower than your idea and therefor your idea should be used whenever possible :-)

Best regards, Robert

ROCLASI:
Hi Robert,

To be honest I am not exactly sure what it does. May it be compiling or syntax checking.
I believe it is transformed into some sort of byte code. I bet one of the Servoyans can tell more.
In any case using eval() you end up with a delay before executing.

Robert Huber:
I agree that eval is slower than your idea and therefor your idea should be used whenever possible :slight_smile:

Just to set the record straight, this tip is not mine.
It was a tip by James Garfield from Adblocks at ServoyWorld 2006. (among all the other goodies like passing objects as arguments, their console module, etc.)

Is there also a way to execute a method within the simpleScript object? For example:

var vCode = 'application.output("hello world"); forms.moon.dialogImAlsoHere();'

The code above is working only with eval(vCode). If I’m doing the following

var simpleScript = new Script(vCode);
simpleScript();

it doesn’t work. But maybe I’m doing something wrong?

Hmm…I see that too.
Would have to dig into that deeper.

Maybe James Garfield can comment on this?
Or one of the Servoyans ?

var fnTxt = " \
   application.output(\"111111111\");  \
   application.output(\"222222\");  \
   // plugins.dialogs.showErrorDialog(\"\", \"test\"); \
   \
";

testFunction = new Script(fnTxt);
testFunction();

The above code worked for me in servoy 3.1

var fnTxt = " \
   application.output(\"111111111\");  \
   application.output(\"222222\");  \
   // plugins.dialogs.showErrorDialog(\"\", \"test\"); \
   \
";

globals.testFunction = new Script(fnTxt);
globals.testFunction();

It seems we can store the object in a global and access the function from other methods.

Also how can I pass parameters to the function?

Thanks a lot!

I’ve never quite figured out how to directly pass arguments to the function, however you can build an object that accomplishes this indirectly.

For example

var sScript = “this.input * this.input”;

var oSquare = new Object();
oSquare.exec = new Script(sScript);

oSquare.input = 5;

//nResult = 25
var nResult = oSquare.exec();

I don’t know how to (if it’s even possible) to access arguments passed in, however, I do know that if the script is part of an object, it can access other parts of that object via the “this” accessor.

In my experience these Scripts can’t natively access globals, forms, etc, but I’ve gotten around this by doing the following

oScript = new Object();
oScript.myGlobals = globals;
oScript.myForms = forms;
oScript.exec = new Script(“//code here”);

With that setup you can access both forms and globals in your script via

this.myForms.formname
or
this.myGlobals.globalname

Enjoy!

Ah! The missing pieces.

Thanks James!

My pleasure. It’s always fun to share secrets :wink:

Hi James,

So if I understand you correctly then you can support any object in Servoy like so (and still use the same syntax):

var oScript = new Object(); 
oScriptglobals = globals; 
oScript.forms = forms; 
oScript.plugins = plugins;
oScript.databaseManager = databaseManager;
oScript.history = history;
oScript.utils = utils;
oScript.security = security;
oScript.i18n = i18n;
oScript.ServoyException = ServoyException;
oScript.exec = new Script("//code here");

Would this still be faster than eval ? I guess it depends on if you have to execute the same script more then once.

I haven’t tested it to that extent, but as far as making logical sense, yes that should work, given how objects are assigned by reference.

As far as being faster, I have only done a few benchmark tests to this effect, but results seem to indicate that new Script is a bit faster. I’m far from saying this is undenyably true, and the amount of speed gain that I noticed is only measured in milliseconds, sometimes hundreds, but never an extreme amount.

It’s really a judgement call on your part, as well as something that can be decided on a case by case basis. Sometimes I find an eval a bit more useful, elegant, etc. Sometimes I know I’m going to be using the script many times (we’ve got a fairly dynamic menu system, and I cache a bunch of objects with scripts attached to them, thereby eliminating the need to do evals all the time).

I’d suggest playing around with both features a bit, and seeing what works best for your individual uses.