Note: Cross posted from IUpdateable from Eric Nelson.
Permalink

[You might want to also read other GuestPosts on my blog – or contribute one?]

On the 26th and 27th of March (2010) myself and Edd Morgan of Microsoft will be popping along to the Scottish Ruby Conference. I dabble with Ruby and I am a huge fan whilst Edd is a “proper Ruby developer”. Hence I asked Edd if he was interested in creating a guest post for my blog on IronRuby.

If you should stumble across this post and happen to be attending the Scottish Ruby Conference, then please do keep a look out for myself and Edd. We would both love to chat about all things Ruby and IronRuby.

This is me and Edd (his head is a lot bigger than mine):

eric09 image

What's IronRuby, and how do I put it on Rails?

IronRuby for Rubyists

IronRuby is Microsoft's implementation of the Ruby language we all know and love with the added bonus of interoperability with the .NET framework — the Iron in the name is actually an acronym for 'Implementation running on .NET'. It's supported by the .NET Common Language Runtime as well as, albeit unofficially, the Mono project. You'd be forgiven for harbouring some question in your mind about running a dynamic language such as Ruby atop the CLR - that's where the DLR (Dynamic Language Runtime) comes in. The DLR is Microsoft's way of providing dynamic language capability on top of the CLR.

Both IronRuby and the DLR are, as part of Microsoft's commitment to open source software, available as part of the Microsoft Public License on GitHub and CodePlex respectively.

IronRuby is designed to be the Ruby implementation of choice on Windows and as such boasts solid compatability and some fantastic performance. IronRuby, at the time of writing, currently hits about an 86% pass rate against RubySpec. For comparison, the MRI interpreter passes about 98%. It also benchmarks considerably (more than 4x) faster than MRI 1.8, as Antonia Cangiano demonstrates with his suite of Ruby benchmarks.

Besides being reasonably compatible and performant, IronRuby's real strength is it's interoperability with the .NET standard library and .NET assemblies in general. With no more than a call to 'require', you can begin using your .NET classes and the framework at large in your Ruby code — 'automatically' providing IronRuby with substantial functionality over the standard Ruby library. require will happily take, as a string, any valid .NET assembly name. Just to illustrate how easy and seamless this exchange between Ruby and .NET is, let's create a new Windows Form from within Ruby.

require 'System.Windows.Forms'
System::Windows::Forms::Form.new.show

 

Run that through ir, the IronRuby interpreter, and you should have upon your screen a standard Windows form! It'll be empty and boring, but what do you expect for just 2 lines? The beauty of this is that it requires notably less ceremony than it's C# or VB counterpart. As you might imagine, you could programmatically add some controls to this new Form:

require 'System.Windows.Forms'
form = System::Windows::Forms::Form.new
lbl = System::Windows::Forms::Label.new
lbl.text = "foo"
form.controls.add(lbl)
form.show

 

Methods that exist in the .NET classes are available in IronRuby in two forms: familiar ruby lowercase form (controls.add) and traditional C# camelcase form (ToString). Since Ruby has no concept of properties in the way most .NET languages do (known as fields to the CLR), properties are implemented in IronRuby as accessor and mutator methods (foo.bar() and foo.bar=()). Let's assume I have MyClassLibrary.dll, the following C# namespace and class Person:

namespace MyClassLibrary
{
    public class Person
    {
        public string Name { get; set; }

        public string Introduce()
        {
            return String.Format("Hi, I'm {0}", Name);
        }
    }
}

 

This is also completely accessible in IronRuby.

require 'MyClassLibrary'
me = MyClassLibrary::Person.new
me # => MyClassLibrary.Person
me.name = "Edd"
me.name #=> 'Edd'
me.introduce # => 'Hi, I'm Edd'

 

This pure interoperability presents very promising reusability of already existing code in IronRuby projects as well as some interesting metaprogramming possibilities.

Note: Watch your casing! If you have a .NET assembly of your own you want to require in your IronRuby, ensure that your .NET code is using proper Upper CamelCase for names of namespaces and classes. .NET classes can directly translate into Ruby classes and .NET namespaces are represented as Ruby modules — both of these are always named using Upper CamelCase in Ruby. If your source names in your .NET code do not match this convention, they cannot be included in your Ruby code.

Riding the irails?

So let's get to the point. I think it's a solid bet to make that a large proportion of Ruby programmers are familiar with the Rails framework - perhaps it's even safe to assume that most were first led to the Ruby language by the siren song of the Rails framework itself.

Long story short, IronRuby is compatible enough to run Rails. Some things of note though:

  • IronRuby has some of it's own scripts that take over the jobs of irb, gem, rake and indeed rails — named iirb, igem, irake and irails respectively. This is to distinguish itself from the regular Ruby you probably have installed alongside it.
    • However, the IronRuby site disclaims that these scripts will be deprecated in favour of calling ir with the -S <task> flag (currently available in the 1.0 RCs).
  • With it's separation from other Ruby installations, IronRuby does not share RubyGems with them (as can be reflected in calling igem list) — although it can.
  • SQLite is quickly becoming the prefered database for development apps. Running under IronRuby, the sqlite3-ruby gem won't do. Be sure to install the sqlite3-ironruby gem.

Note: The MSI IronRuby installer will extract IronRuby to "C:/Program Files/IronRuby x.x" — if you installed IronRuby this way, I advise moving this installation to a directory that does not involve any spaces (and update your PATH appropriately) to avoid any problems with scripts that do not appropriately handle path names.

As stated above, IronRuby is currently very compatible with Ruby 1.8.6. There should be very little problem running an already existing Rails app with IronRuby (run your script/server script with ir — see for yourself).

Since you're probably deploying on Windows, IronRuby takes advantage of it's .NET compatibility to provide SQL Server support (along with Windows integrated security) through the ironruby-sqlserver gem — which requires a different DBI library than the one distributed with Rails, namely ironruby-dbi, but ironruby-sqlserver should take care of that for you. Configuration for this adapter in your database.yml looks like this:

development:
  mode: ADONET
  adapter: sqlserver
  host: HOSTNAME\INSTANCE
  database: application_development
  integrated_security: true

 

Very little beyond this is required to take advantage of IronRuby in your Ruby on Rails applications. Running these applications on a production environment is a huge topic with so many different options — primarily deploying to IIS or Windows Azure, a new, incredibly viable and efficient platform on which to run your web applications and web services that's just perfect for anything running on .NET.

Hopefully by now you have been made aware of the great advantages that arise from combining a fluid, dynamic language such as Ruby with the powerful .NET framework and are wondering; "can I write an ASP.NET MVC application in IronRuby?" or "how well does IronRuby play with other technologies such as Silverlight or its parent WPF for outside-the-browser applications?". Again, if you are attending the Scottish Ruby Conference in March 2010 and would like further information or answers to these questions, please feel free to speak with us at the event.

Edd Morgan