Tuesday, March 1, 2011

Instantiating a Ruby Class that is a Member of a Module from C# (a work around in 2 parts)

Recently I was experimenting with calling my generator ruby scripts from within an ASP.NET MVC 3 project and  I ran into a problem when I attempted to instantiate a class that is a member of a module.  I was sure others had ran into this issue so I hit the internet to see what others have done to get around this issue.  In this blog post I’ll lay out what my issue was and how I found the work around for it.

The Code

Here’s a scaled down version of the ruby class layout that I’m attempting to instantiate:

I took the guts out of the methods since they aren't important. The key here is that the class is in a module. The C# code that I’m trying to instantiate the ruby class in looks like this:

I’m not going to get into the nuts and bolts of how to call into ruby from C# but I am going to give you a quick overview of what the code is doing here.  The first line creates the object we need to call into ruby. I then set up the search path so all the required files can be found.  The next step is to execute the script that has the class I want to instantiate.  Once I have the object I want to execute the run method on the object and return the results.

Line #9 in the C# snippet is where the error was thrown.  It would complain about not being able to find the object.  I tried to use the full name, Generator::CmdLine, and just the class name CmdLine with the same result. After that I went to Google. Everything I found said that a class within a module couldn’t be instantiated from within C#. I found that a bit odd since modules are all over ruby so I turned to StackOverflow.com. 

The Workaround

I posted the question on StackOverflow,   Instantiating a ruby class that is in a module from within C#.  I figured if I’ve run across this problem someone else probably has as well. Within less than 24 hours Shay Friedman author of IronRuby Unleashed had answered my question. Here is what he suggested:

This method is to be placed at the bottom of the cmd_line.rb file outside of the module so it is visible from within the C# code. In the C# code I change the line #9 from the C# code snippet above to this:

Now I call the hack method from C# to get access to the Generator::CmdLine object. The work around got me past the issue I was having and I was able to continue on with my research.

Summary

Having the ability to create objects from ruby classes in C# code is nice but it is not fully functional at this point in time.  However, using resources such as StackOverflow can help you find ways around some of the limitations that currently exist.  I’m also thankful for people like Shay Friedman who take time out of their busy day to help the likes of me. 

This little adventure also has me wondering how many people out there are instantiating objects from Python or Ruby in production or in their day to day work environments.  If you are leave a comment with a brief description of how you are using it and what you think about it.

No comments:

Post a Comment