<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40"><head><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii"><meta name=Generator content="Microsoft Word 14 (filtered medium)"><style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:Tahoma;
        panose-1:2 11 6 4 3 5 4 4 2 4;}
@font-face
        {font-family:Consolas;
        panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p
        {mso-style-priority:99;
        mso-margin-top-alt:auto;
        margin-right:0in;
        mso-margin-bottom-alt:auto;
        margin-left:0in;
        font-size:12.0pt;
        font-family:"Times New Roman","serif";}
p.MsoAcetate, li.MsoAcetate, div.MsoAcetate
        {mso-style-priority:99;
        mso-style-link:"Balloon Text Char";
        margin:0in;
        margin-bottom:.0001pt;
        font-size:8.0pt;
        font-family:"Tahoma","sans-serif";}
span.BalloonTextChar
        {mso-style-name:"Balloon Text Char";
        mso-style-priority:99;
        mso-style-link:"Balloon Text";
        font-family:"Tahoma","sans-serif";}
span.EmailStyle20
        {mso-style-type:personal;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
span.EmailStyle21
        {mso-style-type:personal;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
span.EmailStyle22
        {mso-style-type:personal-reply;
        font-family:"Calibri","sans-serif";
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]--></head><body lang=EN-US link=blue vlink=purple><div class=WordSection1><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>It actually works. Any method call on top-level &#8220;self&#8221; object will fall back to the scope (we inject method_missing to the top-level object if the code is executed from hosting code).<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>It is implemented like instance_eval against the scope.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Tomas<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><div><div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in'><p class=MsoNormal><b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'>From:</span></b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'> ironruby-core-bounces@rubyforge.org [mailto:ironruby-core-bounces@rubyforge.org] <b>On Behalf Of </b>Jimmy Schementi<br><b>Sent:</b> Friday, November 06, 2009 4:48 PM<br><b>To:</b> ironruby-core@rubyforge.org<br><b>Subject:</b> Re: [Ironruby-core] ironruby hosting as scripting engine<o:p></o:p></span></p></div></div><p class=MsoNormal><o:p>&nbsp;</o:p></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Tomas,<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Will &#8220;my_app_object&#8221; be accessible in the do_stuff method? I think not, since our scope variables are just local ruby variables, right? What he&#8217;d really want is to define a method called &#8220;my_app_object&#8221; on the Script class, so then his &#8220;.s&#8221; files can use &#8220;my_app_object&#8221; anywhere, like:<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>engine Execute(@&#8220;class Script<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>&nbsp; def my_app_object<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>&nbsp; &nbsp;&nbsp;# do whatever you need to get the app object<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>&nbsp; end<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>&nbsp; <o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>&nbsp;&nbsp;&lt;script1.s content&gt;<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>end&#8221;)<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>But I still don&#8217;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:<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>~js<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><div style='border:none;border-left:solid blue 1.5pt;padding:0in 0in 0in 4.0pt'><div><div style='border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0in 0in 0in'><p class=MsoNormal><b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'>From:</span></b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'> ironruby-core-bounces@rubyforge.org [mailto:ironruby-core-bounces@rubyforge.org] <b>On Behalf Of </b>Tomas Matousek<br><b>Sent:</b> Friday, November 06, 2009 4:09 PM<br><b>To:</b> ironruby-core@rubyforge.org<br><b>Subject:</b> Re: [Ironruby-core] ironruby hosting as scripting engine<o:p></o:p></span></p></div></div><p class=MsoNormal><o:p>&nbsp;</o:p></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>A better way of exposing application objects to the scripts and vice versa is to use ScriptScope:<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>var engine = IronRuby.CreateEngine();<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>var scope = engine.CreateScope();<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>scope.SetVariable(&#8220;my_app_object&#8221;, new App());<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>engine.Execute(@&#8220;<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>my_app_object.declare 'version 1'<br><br>def do_stuff<br>&nbsp;&nbsp;'success'<br>end<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>&#8221;, scope);<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>var execute = scope.GetVariable&lt;Func&lt;string&gt;&gt;(&#8220;do_stuff&#8221;);&nbsp;&nbsp; <o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Console.WriteLine(execute());<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>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&lt;string&gt; and call the delegate later.<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'>Tomas<o:p></o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=MsoNormal><span style='font-size:11.0pt;font-family:"Calibri","sans-serif";color:#1F497D'><o:p>&nbsp;</o:p></span></p><p class=MsoNormal><b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'>From:</span></b><span style='font-size:10.0pt;font-family:"Tahoma","sans-serif"'> ironruby-core-bounces@rubyforge.org [mailto:ironruby-core-bounces@rubyforge.org] <b>On Behalf Of </b>Dotan N.<br><b>Sent:</b> Friday, November 06, 2009 1:54 PM<br><b>To:</b> ironruby-core@rubyforge.org<br><b>Subject:</b> Re: [Ironruby-core] ironruby hosting as scripting engine<o:p></o:p></span></p><p class=MsoNormal><o:p>&nbsp;</o:p></p><div><p class=MsoNormal style='margin-bottom:12.0pt'>Kevin,<br>Yep i also needed to support input output but it all goes through the &quot;$script&quot; 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 &quot;API&quot; exposed through $script.<br><br>Jimmy,<br>Thanks, I clearly overlooked that.<o:p></o:p></p><div><p class=MsoNormal>On Fri, Nov 6, 2009 at 11:16 PM, Jimmy Schementi &lt;<a href="mailto:Jimmy.Schementi@microsoft.com">Jimmy.Schementi@microsoft.com</a>&gt; wrote:<o:p></o:p></p><div><div><p class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto'><span style='font-size:11.0pt;color:#1F497D'>Your solution sounds fine. To answer you first question though: engine.Execute(&quot;class Script; end&quot;) will always give you nil; classes return nil when defined:</span><o:p></o:p></p><p><span style='font-size:11.0pt;color:#1F497D'>&nbsp;</span><o:p></o:p></p><p class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in'><span style='font-size:11.0pt;font-family:Consolas;color:#1F497D'>&gt;&gt;&gt; class Foo</span><o:p></o:p></p><p class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in'><span style='font-size:11.0pt;font-family:Consolas;color:#1F497D'>... end</span><o:p></o:p></p><p class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;margin-left:.5in'><span style='font-size:11.0pt;font-family:Consolas;color:#1F497D'>=&gt; nil</span><o:p></o:p></p><p class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto'><span style='font-size:11.0pt;color:#1F497D'>&nbsp;</span><o:p></o:p></p><p class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto'><span style='font-size:11.0pt;color:#1F497D'>You&#8217;ll have to do this to get the actual class object:</span><o:p></o:p></p><p class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto'><span style='font-size:11.0pt;color:#1F497D'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><o:p></o:p></p><p class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto;text-indent:.5in'><span style='font-size:11.0pt;font-family:Consolas;color:#1F497D'>engine.Execute(&quot;class Script; end; Script&quot;)</span><o:p></o:p></p><p class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto'><span style='font-size:11.0pt;color:#1F497D'>&nbsp;</span><o:p></o:p></p><p class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto'><span style='font-size:11.0pt;color:#1F497D'>~Jimmy</span><o:p></o:p></p><p class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto'><span style='font-size:11.0pt;color:#1F497D'>&nbsp;</span><o:p></o:p></p><div style='border:none;border-left:solid windowtext 1.5pt;padding:0in 0in 0in 4.0pt;border-color:-moz-use-text-color -moz-use-text-color -moz-use-text-color blue'><div><div style='border:none;border-top:solid windowtext 1.0pt;padding:3.0pt 0in 0in 0in;border-color:-moz-use-text-color -moz-use-text-color'><p class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto'><b><span style='font-size:10.0pt'>From:</span></b><span style='font-size:10.0pt'> <a href="mailto:ironruby-core-bounces@rubyforge.org" target="_blank">ironruby-core-bounces@rubyforge.org</a> [mailto:<a href="mailto:ironruby-core-bounces@rubyforge.org" target="_blank">ironruby-core-bounces@rubyforge.org</a>] <b>On Behalf Of </b>Dotan N.<br><b>Sent:</b> Friday, November 06, 2009 11:17 AM<br><b>To:</b> <a href="mailto:ironruby-core@rubyforge.org" target="_blank">ironruby-core@rubyforge.org</a><br><b>Subject:</b> [Ironruby-core] ironruby hosting as scripting engine</span><o:p></o:p></p></div></div><div><div><p class=MsoNormal style='mso-margin-top-alt:auto;mso-margin-bottom-alt:auto'>&nbsp;<o:p></o:p></p><div><p class=MsoNormal style='mso-margin-top-alt:auto;margin-bottom:12.0pt'>Hi guys sorry for the lengthy mail but i believe this is interesting since i've found a solution that someone else could use.<br><br>just had a session of trying to embed IR in my application.<br>I'm defining a user script which contains some initialization code and a special worker function 'execute'<br><br>this is the &quot;user script&quot;:<br><br>script1.s --------------------------------------------------------<br>$script.declare &quot;version 1&quot;<br><br>def execute<br>&nbsp;&nbsp; $script.report &quot;success&quot;<br>end<br>--------------------------------------------------------<br><br><br>what i'm doing is setting &quot;script&quot; as a global variable that is a gateway to my application.<br>I've tried this way first:<br><br>wrapping script1.s with &quot;class Script &lt;scriopt1.s content&gt; end&quot;<br>and doing Engine.Execute on it.<br><br>I expected to get a RubyObject as a result, which is the Script class.<br><br>then with the RubyObject i would do ObjectOperations.Invoke(&quot;execute&quot;); when ever i wish.<br><br>I had 2 problems:<br><br>1. the RubyObject was always null. any idea why?<br>2. I couldn't really define a global variable properly (i've used the $a = a trick from the forum)<br><br><br><br>eventually i've realized this solution:<br>1. set global variable via RubyContext.DefineGlobalVariable<br>2.&nbsp; i run everything on my script scope and Execute script1.s directly given a ScriptScope<br>3. do InvokeMember on the ScriptScope itself<br><br><br>from googling i've noticed the solution changed a lot along time.<br>so what is the proper way to do it? <br><br><br>Thanks!<o:p></o:p></p></div></div></div></div></div></div><p class=MsoNormal style='margin-bottom:12.0pt'><br>_______________________________________________<br>Ironruby-core mailing list<br><a href="mailto:Ironruby-core@rubyforge.org">Ironruby-core@rubyforge.org</a><br><a href="http://rubyforge.org/mailman/listinfo/ironruby-core" target="_blank">http://rubyforge.org/mailman/listinfo/ironruby-core</a><o:p></o:p></p></div><p class=MsoNormal><o:p>&nbsp;</o:p></p></div></div></div></body></html>