[Ironruby-core] ironruby hosting as scripting engine

Kevin Radcliffe kevin.radcliffe at gmail.com
Wed Nov 11 14:34:38 EST 2009


Tomas, is this new, or changed? I couldn't seem to call a method using
what you showed.
Because "do_stuff" is a function that returns a list (in my case) I couldn't do:

var execute = scope.GetVariable<Func<string>>(“do_stuff”);

But instead, had to do something like this:

return engine.Execute<TOutput>("do_stuff", scope);

In any case, it worked. Just wondering if it won't allow for some
reason because I am expecting a complex type back (IList<string>)

Thanks, -Kevin

On Fri, Nov 6, 2009 at 8:59 PM, Tomas Matousek
<Tomas.Matousek at microsoft.com> wrote:
> Just to be clear, this works:
>
>
>
> public class App { public string Name = “hello”; }
>
>
>
> var engine = IronRuby.CreateEngine();
>
> var scope = engine.CreateScope();
>
> scope.SetVariable(“my_app_object”, new App());
>
>
>
> engine.Execute(@“
>
> def do_stuff
>   my_app_object.name
> end
>
> ”, scope);
>
>
>
> var execute = scope.GetVariable<Func<string>>(“do_stuff”);
>
> Console.WriteLine(execute());
>
>
>
> Tomas
>
>
>
>
>
> From: ironruby-core-bounces at rubyforge.org
> [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Tomas Matousek
> Sent: Friday, November 06, 2009 7:53 PM
>
> To: ironruby-core at rubyforge.org
> Subject: Re: [Ironruby-core] ironruby hosting as scripting engine
>
>
>
> It actually works. Any method call on top-level “self” object will fall back
> to the scope (we inject method_missing to the top-level object if the code
> is executed from hosting code).
>
> It is implemented like instance_eval against the scope.
>
>
>
> Tomas
>
>
>
> From: ironruby-core-bounces at rubyforge.org
> [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Jimmy Schementi
> Sent: Friday, November 06, 2009 4:48 PM
> To: ironruby-core at rubyforge.org
> Subject: Re: [Ironruby-core] ironruby hosting as scripting engine
>
>
>
> Tomas,
>
>
>
> Will “my_app_object” be accessible in the do_stuff method? I think not,
> since our scope variables are just local ruby variables, right? What he’d
> really want is to define a method called “my_app_object” on the Script
> class, so then his “.s” files can use “my_app_object” anywhere, like:
>
>
>
> engine Execute(@“class Script
>
>   def my_app_object
>
>     # do whatever you need to get the app object
>
>   end
>
>
>
>   <script1.s content>
>
> end”)
>
>
>
> But I still don’t like wrapping the user script in a class like that. The
> preferred way would be to create an instance of script and call
> instance_eval with the contents of the script1.s file:
>
>
>
> ~js
>
>
>
> From: ironruby-core-bounces at rubyforge.org
> [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Tomas Matousek
> Sent: Friday, November 06, 2009 4:09 PM
> To: ironruby-core at rubyforge.org
> Subject: Re: [Ironruby-core] ironruby hosting as scripting engine
>
>
>
> A better way of exposing application objects to the scripts and vice versa
> is to use ScriptScope:
>
>
>
> var engine = IronRuby.CreateEngine();
>
> var scope = engine.CreateScope();
>
> scope.SetVariable(“my_app_object”, new App());
>
>
>
> engine.Execute(@“
>
> my_app_object.declare 'version 1'
>
> def do_stuff
>   'success'
> end
>
> ”, scope);
>
>
>
> var execute = scope.GetVariable<Func<string>>(“do_stuff”);
>
> Console.WriteLine(execute());
>
>
>
> Top level Ruby methods defined in the executed script are published to the
> scope so that the host can read it via GetVariable method. Also, Ruby
> methods are convertible to delegates, so you can get the variable as
> Func<string> and call the delegate later.
>
>
>
> Tomas
>
>
>
>
>
> From: ironruby-core-bounces at rubyforge.org
> [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Dotan N.
> Sent: Friday, November 06, 2009 1:54 PM
> To: ironruby-core at rubyforge.org
> Subject: Re: [Ironruby-core] ironruby hosting as scripting engine
>
>
>
> Kevin,
> Yep i also needed to support input output but it all goes through the
> "$script" variable back to the backing C# object. for now, it makes it
> easier to have events and debugging. all in all the end result is that i
> provide an "API" exposed through $script.
>
> Jimmy,
> Thanks, I clearly overlooked that.
>
> On Fri, Nov 6, 2009 at 11:16 PM, Jimmy Schementi
> <Jimmy.Schementi at microsoft.com> wrote:
>
> Your solution sounds fine. To answer you first question though:
> engine.Execute("class Script; end") will always give you nil; classes return
> nil when defined:
>
>
>
>>>> class Foo
>
> ... end
>
> => nil
>
>
>
> You’ll have to do this to get the actual class object:
>
>
>
> engine.Execute("class Script; end; Script")
>
>
>
> ~Jimmy
>
>
>
> From: ironruby-core-bounces at rubyforge.org
> [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Dotan N.
> Sent: Friday, November 06, 2009 11:17 AM
> To: ironruby-core at rubyforge.org
> Subject: [Ironruby-core] ironruby hosting as scripting engine
>
>
>
> Hi guys sorry for the lengthy mail but i believe this is interesting since
> i've found a solution that someone else could use.
>
> just had a session of trying to embed IR in my application.
> I'm defining a user script which contains some initialization code and a
> special worker function 'execute'
>
> this is the "user script":
>
> script1.s --------------------------------------------------------
> $script.declare "version 1"
>
> def execute
>    $script.report "success"
> end
> --------------------------------------------------------
>
>
> what i'm doing is setting "script" as a global variable that is a gateway to
> my application.
> I've tried this way first:
>
> wrapping script1.s with "class Script <scriopt1.s content> end"
> and doing Engine.Execute on it.
>
> I expected to get a RubyObject as a result, which is the Script class.
>
> then with the RubyObject i would do ObjectOperations.Invoke("execute"); when
> ever i wish.
>
> I had 2 problems:
>
> 1. the RubyObject was always null. any idea why?
> 2. I couldn't really define a global variable properly (i've used the $a = a
> trick from the forum)
>
>
>
> eventually i've realized this solution:
> 1. set global variable via RubyContext.DefineGlobalVariable
> 2.  i run everything on my script scope and Execute script1.s directly given
> a ScriptScope
> 3. do InvokeMember on the ScriptScope itself
>
>
> from googling i've noticed the solution changed a lot along time.
> so what is the proper way to do it?
>
>
> Thanks!
>
> _______________________________________________
> Ironruby-core mailing list
> Ironruby-core at rubyforge.org
> http://rubyforge.org/mailman/listinfo/ironruby-core
>
>
>
> _______________________________________________
> Ironruby-core mailing list
> Ironruby-core at rubyforge.org
> http://rubyforge.org/mailman/listinfo/ironruby-core
>
>


More information about the Ironruby-core mailing list