Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to embed a ruby gem into a C# project and require it from an embedded IronRuby script?

I have a C# project in which I have embedded an IronRuby program. The project (including my ruby script) is compiled to an .exe file in Visual Studio 2010 for distribution. I'm using a pattern similar to this for bootstrapping the IronRuby script: http://pastebin.com/NKes1cyc (and Jimmy Schementi goes into more detail here: http://blog.jimmy.schementi.com/2009/12/ironruby-rubyconf-2009-part-35.html).

My problem: I would like to embed a gem (json_pure) in my C# assembly and call it from the ruby script.

Some resources I've found:

  1. In JRuby, you can easily package a gem into a jar file and then simply require the jar file at runtime - http://blog.nicksieger.com/articles/2009/01/10/jruby-1-1-6-gems-in-a-jar

  2. The irpack tool (at http://github.com/kumaryu/irpack) is capable of compiling Ruby into an .exe (I think it dynamically creates and compiles a C# project) while embedding the ruby standard library. But it looks like it is only embedding the pre-built IronRuby .dlls, not ruby .rb files. The approach this tool uses would work if I could figure out how to compile Ruby source files into a .dll.

How do I embed an IronRuby gem into a C# assembly (or compile an IronRuby gem to a .dll)?

EDIT:

Page 472 of IronRuby In Action ("Using External Libraries") explains how to require standard ruby libraries from within an embedded ruby file. It involves adding the folder(s) to the runtime search paths collection, as follows (edited for brevity and clarity):

ScriptEngine engine = IronRuby.Ruby.CreateEngine();
var searchPaths = engine.GetSearchPaths().Concat(new[] 
{
    "C:\\Program Files (x86)\\IronRuby 1.1\\Lib\\ruby\\1.9.1",
    "C:\\Program Files (x86)\\IronRuby 1.1\\Lib\\ironruby"
});
engine.SetSearchPaths(searchPaths)

This approach assumes the host machine has IronRuby installed, but I want to embed ruby files (from a gem) into the assembly so it can be run without IronRuby pre-installed.

EDIT 2 (further research):

Reading through the source code of the irpack tool referenced above, I notice that Kumaryu is embedding resources into the final assembly via the System.IO.Packaging.Package class, and then passing the package into the call to msbuild (see https://github.com/kumaryu/irpack/blob/master/lib/irpack/packager.rb). Perhaps some further research into packaging files into an executable would lead to a solution. The problem I see is that ruby files in a gem require other ruby files... can a ruby file in an assembly package require other ruby files in the same package?

EDIT 3:

I haven't gotten any further to an answer yet, but I'd be interested to hear anyone's feedback, even if it's just a link or a suggestion about where to look. I'm new to msbuild, and the documentation is pretty hefty. An initial web search for "msbuild embed zip package" didn't reveal anything relevant.

like image 684
Roy Tinker Avatar asked Feb 17 '12 18:02

Roy Tinker


1 Answers

Require is a method that can be overridden like any other ruby method. I think that is how the original ruby gems package worked, gems would simply override require.

If you can package the gem into your .exe somehow, you can override require to load from the assembly.

like image 155
sbridges Avatar answered Oct 06 '22 00:10

sbridges