Joshua M.
2011-Jan-13 20:51 UTC
[Ironruby-core] Accessing a Module''s Classes from C# with dynamic
Hey guys. I am currently experimenting with IronRuby as an extensibility solution for my application. However, I have hit a roadblock. What I would like to do is call Runtime.UseFile("script.rb"), then access a global module in the script, and instantiate a specific class in that module. Here is the script file for reference: module RbScriptApp class Foo def Bar() return (rand(100) + 1).to_s(); end end end Initially, I thought it would be as easy as typing dynamic globals = myRuntime.Globals; dynamic myClass = globals.RbScriptApp.Foo. at new(); myClass.Bar(); ... but I soon found out this was not the case, as the builtin RubyModule class does not support this dynamic syntax. Is there a way around this or is it just plain impossible? I was unable to find *any* information about how to do this (not even about RubyModule itself!) through Google. The exception in question is a RuntimeBinderException: ''IronRuby.Builtins.RubyModule'' does not contain a definition for ''Foo'' Right now my workaround is a call to EnumerateConstants and manual lookup of the class name I want, but it doesn''t have the syntactic elegance of the dynamic keyword... Any thoughts? Thanks. -- Posted via http://www.ruby-forum.com/.
Joshua M.
2011-Jan-15 07:55 UTC
[Ironruby-core] Accessing a Module''s Classes from C# with dynamic
It turns out that the problem is not accessing a module''s class, but accessing the contents of a module in a require''d file. global.rb require ''app'' app.rb module RbScriptApp class Foo def Bar() return (rand(100) + 1).to_s() end end end No matter what I do I can only access RbScriptApp and not Foo if I call Runtime.UseFile("global.rb"). So far I have two other work arounds: 1.) create wrapper methods for everything I want to access in app.rb (ugh), or 2.) use Engine.Execute("RbScriptApp::Foo.new"). The latter is more preferrable, I suppose, but it seems strange that I can''t access Foo by dynamic. Any more information about this issue would be very helpful and appreciated. -- Posted via http://www.ruby-forum.com/.
Will Green
2011-Jan-15 12:58 UTC
[Ironruby-core] Accessing a Module''s Classes from C# with dynamic
On Jan 15, 2011, at 2:55 AM, Joshua M. wrote:> No matter what I do I can only access RbScriptApp and not Foo if I call > Runtime.UseFile("global.rb"). So far I have two other work arounds: 1.) > create wrapper methods for everything I want to access in app.rb (ugh), > or 2.) use Engine.Execute("RbScriptApp::Foo.new"). The latter is more > preferrable, I suppose, but it seems strange that I can''t access Foo by > dynamic.That''s how Modules work in Ruby. Just like namespaces in C#. Try adding include RbScriptApp to your global.rb file. You need to include the Module if you want to access the class without qualifying it.> Any more information about this issue would be very helpful and > appreciated. > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Ironruby-core mailing list > Ironruby-core at rubyforge.org > http://rubyforge.org/mailman/listinfo/ironruby-core-- Will Green will at hotgazpacho.org
Tomas Matousek
2011-Jan-15 17:53 UTC
[Ironruby-core] Accessing a Module''s Classes from C# with dynamic
Another option would be RbScriptApp.const_get("Foo") I haven''t tried that, but I think it should work. Neither solution is indeed ideal. CLR interop with Modules isn''t quite polished yet. Tomas -----Original Message----- From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Joshua M. Sent: Friday, January 14, 2011 11:55 PM To: ironruby-core at rubyforge.org Subject: Re: [Ironruby-core] Accessing a Module''s Classes from C# with dynamic It turns out that the problem is not accessing a module''s class, but accessing the contents of a module in a require''d file. global.rb require ''app'' app.rb module RbScriptApp class Foo def Bar() return (rand(100) + 1).to_s() end end end No matter what I do I can only access RbScriptApp and not Foo if I call Runtime.UseFile("global.rb"). So far I have two other work arounds: 1.) create wrapper methods for everything I want to access in app.rb (ugh), or 2.) use Engine.Execute("RbScriptApp::Foo.new"). The latter is more preferrable, I suppose, but it seems strange that I can''t access Foo by dynamic. Any more information about this issue would be very helpful and appreciated. -- Posted via http://www.ruby-forum.com/. _______________________________________________ Ironruby-core mailing list Ironruby-core at rubyforge.org http://rubyforge.org/mailman/listinfo/ironruby-core
Joshua M.
2011-Jan-15 21:15 UTC
[Ironruby-core] Accessing a Module''s Classes from C# with dynamic
>You need to include the Module if you want to >access the class without qualifying it.I have tried this but it doesn''t work (RuntimeBinderException: ''Microsoft.Scripting.Hosting.ScriptScope'' does not contain a definition for ''Foo''). In my original post I had specified the fully qualified name.>RbScriptApp.const_get("Foo")InvalidOperationException: Empty scope has no global scope.>I haven''t tried that, but I think it should work. Neither solution is >indeed ideal. CLR interop with Modules isn''t quite polished yet.Ah, that would explain it. I guess I''ll hold off on integrating IronRuby just yet. -- Thank you both for your time. -- Posted via http://www.ruby-forum.com/.
Rob R.
2011-Feb-24 14:41 UTC
[Ironruby-core] Accessing a Module''s Classes from C# with dynamic
to add directories to your search path from within C# you can do something like this: var engine = Ruby.CreateEngine(); var searchPaths = engine.GetSearchPaths().ToList(); searchPaths.Add(@"c:\code\generator\lib"); searchPaths.Add(@"C:\Ruby-ri-192\lib\ruby\1.9.1"); engine.SetSearchPaths(searchPaths); Let me know if you find out how to access classes that are within modules from C#. I''m having no luck. -- Posted via http://www.ruby-forum.com/.
Shay Friedman
2011-Feb-25 06:38 UTC
[Ironruby-core] Accessing a Module''s Classes from C# with dynamic
I got it working using a kind of a hack/workaround. I know this is kind of a hack/workaround, but I managed to do it this way: I added the next code to the end of the ruby file: def hack(s) eval(s) end And then used it from the C# code to get the class object: var engine = Ruby.CreateEngine(); var scope engine.ExecuteFile(@"c:\code\generator\lib\generator\generator_cmd_line.rb"); var genCmdLineObj = engine.Execute(String.Format("hack(''{0}::{1}'')", "Generator", "CmdLine"), scope); var cmdLineObj = engine.Operations.CreateInstance(genCmdLineObj); var results = engine.Operations.InvokeMember(cmdLineObj, "run"); return Content(results); Kind of a hack, but hey, it works! :) Shay. -------------------------------------------------------- Shay Friedman | Co-Founder @ CodeValue <http://codevalue.net/> | C#/IronRuby MVP | Author of IronRuby Unleashed Blog: http://IronShay.com <http://ironshay.com/> | Twitter: http://twitter.com/ironshay On Thu, Feb 24, 2011 at 4:41 PM, Rob R. <lists at ruby-forum.com> wrote:> to add directories to your search path from within C# you can do > something like this: > > > var engine = Ruby.CreateEngine(); > var searchPaths = engine.GetSearchPaths().ToList(); > searchPaths.Add(@"c:\code\generator\lib"); > searchPaths.Add(@"C:\Ruby-ri-192\lib\ruby\1.9.1"); > engine.SetSearchPaths(searchPaths); > > Let me know if you find out how to access classes that are within > modules from C#. I''m having no luck. > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Ironruby-core mailing list > Ironruby-core at rubyforge.org > http://rubyforge.org/mailman/listinfo/ironruby-core >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/ironruby-core/attachments/20110225/31c3952c/attachment-0001.html>
Tomas Matousek
2011-Feb-25 08:25 UTC
[Ironruby-core] Accessing a Module''s Classes from C# with dynamic
Wouldn''t this work? dynamic globalConstants = engine.Runtime.Globals globalConstants.MyModule.const_get(''MyClass'') assuming module MyModule class MyClass end end Haven''t tried. Let me know if it works. Tomas From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Shay Friedman Sent: Thursday, February 24, 2011 10:38 PM To: ironruby-core at rubyforge.org Subject: Re: [Ironruby-core] Accessing a Module''s Classes from C# with dynamic I got it working using a kind of a hack/workaround. I know this is kind of a hack/workaround, but I managed to do it this way: I added the next code to the end of the ruby file: def hack(s) eval(s) end And then used it from the C# code to get the class object: var engine = Ruby.CreateEngine(); var scope = engine.ExecuteFile(@"c:\code\generator\lib\generator\generator_cmd_line.rb"); var genCmdLineObj = engine.Execute(String.Format("hack(''{0}::{1}'')", "Generator", "CmdLine"), scope); var cmdLineObj = engine.Operations.CreateInstance(genCmdLineObj); var results = engine.Operations.InvokeMember(cmdLineObj, "run"); return Content(results); Kind of a hack, but hey, it works! :) Shay. -------------------------------------------------------- Shay Friedman | Co-Founder @ CodeValue<http://codevalue.net/> | C#/IronRuby MVP | Author of IronRuby Unleashed Blog: http://IronShay.com<http://ironshay.com/> | Twitter: http://twitter.com/ironshay On Thu, Feb 24, 2011 at 4:41 PM, Rob R. <lists at ruby-forum.com<mailto:lists at ruby-forum.com>> wrote: to add directories to your search path from within C# you can do something like this: var engine = Ruby.CreateEngine(); var searchPaths = engine.GetSearchPaths().ToList(); searchPaths.Add(@"c:\code\generator\lib"); searchPaths.Add(@"C:\Ruby-ri-192\lib\ruby\1.9.1"); engine.SetSearchPaths(searchPaths); Let me know if you find out how to access classes that are within modules from C#. I''m having no luck. -- Posted via http://www.ruby-forum.com/. _______________________________________________ Ironruby-core mailing list Ironruby-core at rubyforge.org<mailto:Ironruby-core at rubyforge.org> http://rubyforge.org/mailman/listinfo/ironruby-core -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/ironruby-core/attachments/20110225/6ee60552/attachment.html>
Shay Friedman
2011-Feb-25 11:05 UTC
[Ironruby-core] Accessing a Module''s Classes from C# with dynamic
const_get doesn''t work, but you can do globalConstants.MyModule.constants()[0] but then you get back an object which you can''t initialize... Shay. On Fri, Feb 25, 2011 at 10:25 AM, Tomas Matousek < Tomas.Matousek at microsoft.com> wrote:> Wouldn?t this work? > > > > dynamic globalConstants = engine.Runtime.Globals > > > > globalConstants.MyModule.const_get(?MyClass?) > > > > assuming > > > > module MyModule > > class MyClass > > end > > end > > > > Haven?t tried. Let me know if it works. > > > > Tomas > > > > *From:* ironruby-core-bounces at rubyforge.org [mailto: > ironruby-core-bounces at rubyforge.org] *On Behalf Of *Shay Friedman > *Sent:* Thursday, February 24, 2011 10:38 PM > > *To:* ironruby-core at rubyforge.org > *Subject:* Re: [Ironruby-core] Accessing a Module''s Classes from C# with > dynamic > > > > I got it working using a kind of a hack/workaround. > > > > I know this is kind of a hack/workaround, but I managed to do it this way: > > > > I added the next code to the end of the ruby file: > > > > def hack(s) > > eval(s) > > end > > > > And then used it from the C# code to get the class object: > > > > var engine = Ruby.CreateEngine(); > > > > var scope > engine.ExecuteFile(@"c:\code\generator\lib\generator\generator_cmd_line.rb"); > > > > var genCmdLineObj = engine.Execute(String.Format("hack(''{0}::{1}'')", > "Generator", "CmdLine"), scope); > > > > var cmdLineObj = engine.Operations.CreateInstance(genCmdLineObj); > > var results = engine.Operations.InvokeMember(cmdLineObj, "run"); > > return Content(results); > > > > Kind of a hack, but hey, it works! :) > > > > Shay. > > -------------------------------------------------------- > > Shay Friedman | Co-Founder @ CodeValue <http://codevalue.net/> | > C#/IronRuby MVP | Author of IronRuby Unleashed > > Blog: http://IronShay.com <http://ironshay.com/> | Twitter: > http://twitter.com/ironshay > > > > > > On Thu, Feb 24, 2011 at 4:41 PM, Rob R. <lists at ruby-forum.com> wrote: > > to add directories to your search path from within C# you can do > something like this: > > > var engine = Ruby.CreateEngine(); > var searchPaths = engine.GetSearchPaths().ToList(); > searchPaths.Add(@"c:\code\generator\lib"); > searchPaths.Add(@"C:\Ruby-ri-192\lib\ruby\1.9.1"); > engine.SetSearchPaths(searchPaths); > > Let me know if you find out how to access classes that are within > modules from C#. I''m having no luck. > > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > 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 > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/ironruby-core/attachments/20110225/31762924/attachment.html>