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>