What is the scope of script?

Jun 6, 2013 at 1:49 PM
Edited Jun 6, 2013 at 2:11 PM
I've been trying to compile and run a combination of scripts, and I keep running into the same problem with Jurassic, 'Jurassic.JavaScriptException: TypeError: 'myThing.myFunction' is not a function'. If I execute some code to add a variable to point to 'myThing.myFunction', then it works, similarly if i evaluate 'typeof myThing.myFunction' then the result is 'function'.

Can anyone explain why this is? What is the scope of code that has been executed on an instance of ScriptEngine? Is the code run in the Execute and ExecuteFile methods added to the global scope of the instance of engine?
Jun 6, 2013 at 4:04 PM
Some actual code might help...


Coordinator
Jun 6, 2013 at 10:13 PM
Is the code run in the Execute and ExecuteFile methods added to the global scope of the instance of engine?
Yes. If you think about it, there's not really any other way it could work.

I can't tell you why you're getting "'myThing.myFunction' is not a function" though, because it depends on the context of where you are trying to call that function. (Remember that Execute and ExecuteFile always operate from the global context, but function calls can be made from within global or non-global contexts)
Jul 22, 2013 at 11:17 AM
Edited Jul 22, 2013 at 11:52 AM
Here's a code sample.
        var engine = new ScriptEngine();
        string text = "<footer role=\"contentinfo\">\r\n\t<p>&#169; {{.}}</p>\r\n</footer>";
        engine.ExecuteFile("\\\\Com.Web\\Com.Web.UIAssets\\UIAssets\\js\\handlebars.js");
        var output = engine.CallGlobalFunction<string>("Handlebars.compile", text);
Handlebars.compile method is a function, yet the CallGlobalFunction method says it is not. I assume functions executed by CallGlobalFunction need to be global, and not methods attached to a global object? Is there a separate method to execute Javascript methods which are part of objects? Do i need to call the Evaluate method?

Thanks
Jul 22, 2013 at 12:26 PM
This is just a guess, but CallGlobalFunction probably needs the function to be attatched to the global object, which "Handlebars.compile" is not. In the case of "Handlebars.compile", "Handlebars" (an object/function/whatever) is attached to the global object, but the function "compile" is attached to "Handlebars". You should probably do something like this:
var fn = (Function)engine.Evaluate("Handlebars.compile");
fn.Invoke(engine, ......);
I'm affraid to say I can't remember the signatures or class-names, but use intellisence to find a class named something like "Function" in Jurassic, and look for an "Invoke" or "Call" method on that. Should work for you :).


Coordinator
Jul 22, 2013 at 12:33 PM
To save you messing around with intellisense :-)
var fn = (FunctionInstance)engine.Evaluate("Handlebars.compile");
var output = fn.Call(engine.Evaluate("Handlebars"), text);
Jul 22, 2013 at 2:06 PM
Ah, makes sense, thanks. Is FunctionInstance documented somewhere?
Coordinator
Jul 22, 2013 at 10:06 PM
Edited Jul 22, 2013 at 10:07 PM
dob wrote:
Ah, makes sense, thanks. Is FunctionInstance documented somewhere?
Sure, the documentation is here: https://jurassic.codeplex.com/SourceControl/latest#Jurassic/Library/Function/FunctionInstance.cs

Okay, that might not have been what you were looking for! There is some documentation, but it only covers the basics. Like most developers, I consider documentation the bane of my existence ;-)
Jul 23, 2013 at 8:17 AM
Heh, thanks, all working now.
Jul 23, 2013 at 9:43 AM
Paul: How well xml-annotated (///) is the Jurassic Sources btw?


Jul 23, 2013 at 9:45 AM
Hmm, looking over some random classes in Jurassic, it seems to be rather well documented...
Does your NuGet package contain the .xml-file for the dll? (I don't find any nuget-ref in your sources...)


Coordinator
Jul 23, 2013 at 10:51 PM
Thanks! As a hobby project with no deadlines, I decided early on to take my time and make something that I could be proud of :-)

Re: the nuget package, I don't know to be honest, I wasn't the one who created it.
Jul 24, 2013 at 12:27 PM
Yeah, Jurassic is fairly awesome. Though I've been considering making a "competing" project using DLR (though it'd just be for fun, cause I like messing with the DLR) xD.
But what I'm currently working on is documentation-generation (and hosting). I guess you wouldn't mind getting a shiny API-documentation automatically (sandcastle style, but without you having to lift a finger) generated for Jurassic?