Ruby In Steel Archives

Back to -Ruby In Steel Archives

Ruby.NET - Integrating the Gardens Point Compiler

A few simple tweaks let you compile Ruby to .NET inside Ruby In Steel

The Gardens Point Ruby .NET compiler is an ambitious project from the Queensland University of Technology. The latest release (beta 0.6) passes all 871 tests in the Ruby 1.8.2 test suite and work is now being done to make the compiler play nicely with Rails.

A .NET Ruby compiler sounds like something that would be nice to use from inside Ruby In Steel. Here I’ll explain how I went about adding a menu item to let me compile the selected file using the Gardens Point compiler…

The first thing I had to do was to add the compiler as an external tool. You do this via the Tools, External Tools menu. In the External Tools dialog, you can add the command to run the compiler and pass it the fully qualified path to the active source file by entering $(ItemPath) into the Arguments field.

You need to set up all the paths and arguments in the External Tools dialog.

This didn’t initially work as expected, however. When I tried running the compiler from the Tools menu I kept seeing a warning stating “Illegal characters in path”. It took me quite some time to find what this problem was. Eventually I discovered that when Visual Studio passes a path as an argument (a directory name or a file name) it places it between double-quotes. The Ruby compiler, unfortunately, doesn’t like double-quotes and, as far as I can figure out, there is no way to tell Visual Studio to stop using them.

My first thought was to write a little Ruby program to do some simple string processing by removing quotes and then pass on the quote-free arguments to the compiler. In fact, when I tried this out, I realised that no explicit string processing is necessary. When Ruby receives quoted arguments, it strips the quotes automatically. So, this is the Ruby pre-processor which I ended up writing:

args = ""
  | arg |
  args += ( " " + arg )
puts( `rubycompiler #{args}` )

This simply parses out any command line arguments, ARGV, passing each argument into a block and putting a space in front of it (otherwise all the arguments would be concatenated without any separators). The string thus formed, args, is then evaluated #{args} in a back-quoted string which begins with rubycompiler. Ruby’s backquoted strings are executed as commands so this has the same effect as entering the command rubycompiler plus any unquoted arguments at the system prompt.

I placed this Ruby code file, which I called vsrubycomp.rb into the same directory as the ruby compiler and compiled it using the command:

rubycompiler –exe vsrubycomp.rb

This created an executable file, vsrubycomp.exe, in the same directory. Now all that I had to do was to set up this new executable as my external tool. In the External Tools dialog I clicked Add to create a new item and entered the following details:

Title: VSRubyCompiler
Command: vsrubycomp.exe
Arguments: --exe $(ItemPath)
Initial Directory: C:\Huw\Programming\Ruby\RubyNetBeta06\Bin\

Here the Initial Directory is the one in which the binary files of the Ruby Compiler plus my little pre-processor, vsrubycomp.exe are located.

Having done this, when I select the VSRubyCompiler from the Tools menu, the ruby compiler does indeed compile the currently active Ruby source file in Ruby In Steel. Unfortunately, even though I have specifically set the Initial Directory to the location of the Ruby compiler, the executable output is placed into the same directory as the Ruby source file rather than into the directory containing the compiler (as I had intended).

Moreover, in my experience, the behaviour of compiled programs is not always what you might expect. Some of the differences are minor. However, I’ve had one significant (and baffling) problem when using gets to prompt the user for input. My compiled programs just continue running past the gets without pausing. I don’t know why this is; maybe I’m missing some option or switch somewhere? I’m not yet sufficiently familiar with the compiler to know all the ins and outs of its usage. Anyhow, if I find a solution for this I’ll post it in this blog later.

The executable produced by the compiler needs access to three DLLs (in the same directory as the compiler). This means that any attempt to run the executable in its original location, will fail. There are a few ways to get around this. You could copy the executable into the compiler directory; you could copy the three DLLs into the project directory containing the source code and the new .exe; or you could place the three DLLs into the Global Assembly cache (copy them into C:\Windows\assembly).

To run the executable, open a command prompt in the selected directory of the Solution Explorer.

It would be nice if the compiler were to provide an option to let you specify the output directory (that is, the directory into which the .exe is placed). That would make for smoother integration with Ruby In Steel. For me, though, the really interesting stuff is still to come when interoperability with other .NET languages, such as C#, is promised. I for one would love to be able to create mixed C# and Ruby projects right inside Ruby In Steel. That would then give Ruby programmers easy access to the full feature set of the Visual Studio .NET development tools.

Ah, what a happy thought!

Bookmark and Share   Keywords:  .NET  tools
© SapphireSteel Software 2014