IronRuby at OSCON 2009: Mono, Moonlight, and scripting open source apps
Today I’ll be giving a talk at OSCON 2009 titled “IronRuby 0.9”. For any new readers, IronRuby is an Open Source implementation of the Ruby programming language for the Microsoft .NET Framework; it brings the expressiveness of Ruby to .NET, and the capabilities of .NET to Ruby. I’ll walk you through the talk in this post:
- Road to IronRuby 1.0
- Running the same application on the desktop and in the browser, on most major platforms (Windows, Mac OS, Linux) and most major browsers (Firefox, Safari, Internet Explorer)
- Detour – Gestalt: Running Ruby and Python in the browser, again.
- Using code written in any C# and Python from Ruby without it feeling foreign.
- How IronRuby has improved in the past 6 months, and how you can help IronRuby become a 1.0 quality implementation.
Road to IronRuby 1.0
It’s been a long ride since IronRuby was announced alongside Silverlight at MIX ‘07, but in a few days the 0.9 version will be available, and all eyes will be focused on getting it to 1.0. The past couple of versions have made vast compatibility and performance improvements, and 0.9 marks the last set of major features that will be added to IronRuby. From now on, all IronRuby languages will be primarily focused on bug fixing and anything else the community deems necessary to call IronRuby a 1.0 release. These improvements be delivered as point-point releases (0.9.1, 0.9.2, etc) until you decide it is ready to call 1.0.
But we’ll dive into the numbers and metrics at the end; let’s talk about why IronRuby is useful in your toolkit.
Cross-platform, cross-browser Ruby implementation
Whenever people hear .NET [they first think about a top-level domain, but when in the context of “Microsoft”] they immediately think “Windows”. But Miguel and the Mono team have shown that isn’t reality. They’ve built a open-source implementation of .NET which runs on Linux, Mac OS, and also Windows. They are also building a open-source Silverlight 2 implementation, called Moonlight, allowing Silverlight applications to run on Linux browsers supporting Mozilla’s plug-in architecture; Silverlight 2 runs on Intel Macs and Windows. Since IronRuby runs on .NET and Silverlight, it also runs on Mono and Moonlight. Let’s explore that a bit:
With Microsoft.NET and Mono, IronRuby can run on Windows and Linux (anywhere Mono runs, including Mac OS).
You’ll notice that real Ruby code runs, it’s running on a Unix environment on Mono, and .NET types can be accessed in a Ruby-esk way, even generic types.
Because IronRuby integrates directly with .NET, you can use any existing .NET code from IronRuby. This means that any frameworks, be them Windows Forms, Windows Presentation Foundation (WPF), or GTK(#), can be used from IronRuby because .NET and Mono [respectively] have CLI bindings for these frameworks. Mono even has a Windows Forms implementation that translates to GTK, so the same application can run unmodified on both implementations. Mono only supports the “Silverlight” subset of WPF, which I’ll elaborate on in a bit.
There’s also a tiny subset of .NET which is part of a browser plug-in called Silverlight; Microsoft’s implementation runs on Windows and Mac, in Firefox, Safari, and Internet Explorer (though any browser which supports ActiveX, Mozilla’s, or Safari’s plug-in architecture should work fine, like Opera or Chrome).
The IronRuby tutorial application runs as a WPF desktop application (on the left), as well as Silverlight application (on the right).
Also, Silverlight 3 supports running applications out of the browser, very simply on Windows and Mac OS by right-clicking on the Silverlight application and selecting “Install”.
Through Moonlight the IronRuby tutorial app also runs on Linux:
Mono also supports running Moonlight applications through GTK on the desktop, just as a WPF application would work. While direct support isn’t in current daily builds of Moonlight, Miguel shows how easy it is to make the same code target the browser with Moonlight and the Linux desktop with Mono, just using C# code:
Note: the latest Moonlight stable release will not work for IronRuby, you must install the latest Moonlight build from their build bot: http://sublimeintervention.com:8123/GetFile.aspx?id=11487919
Detour: Gestalt –- Ruby and Python in the browser
It uses Silverlight to do this, so this will work in Moonlight as well.
Dynamic and Static language interop
IronRuby has great integration with the .NET framework APIs, so C#/VB code can be called from IronRuby without it feeling like “interop”. C# can also call IronRuby through the Dynamic Language Runtime (DLR) Hosting APIs. However, in .NET 4.0 dynamic method dispatch is part of C#, so calling IronRuby from C# is just as easy as a C# method call. Being that IronRuby is built on the DLR, it can interoperate with other DLR languages just as easily, so Python and Ruby play along nicely today, and future DLR languages as well.
A simple way to show that capability is by writing a unit test for a class in .NET; let’s pick “Stack”:
As you can see, creating .NET types, calling methods on .NET classes, and all the other language features Ruby has work against .NET types (even re-opening .NET classes).
To show the reverse, lets look at a very simple REPL implementation:
In less than 100 lines of code, you have a program that runs arbitrary Python and Ruby code. The DLR hosting API lets you run dynamic language code from a static language just from strings.
Expanding on these ideas, let us give the experience a upgrade to the 21st century. John Lam has shown this before at TechEd 2009: an editor that can double as a REPL.
This seems like a great idea, and it is even better once you start using it. It works like a normal editor, but selecting a block of code and pressing ctrl-e will run the code, showing the output directly below selected code as a comment, and ctrl-enter runs the current line. The code that gets run gets syntax highlighted. There is no need to have up-down-cursor history, as it’s all right there in the editor. If you need to modify something you’ve already run just, just modify it in the editor and re-run it! This integrates the editor-repl experience, making it a very valuable tool.
Note: this is not a new idea by any means, as TextMate does something similar, but no one seems to explain this as an upgrade to your traditional REPL.
Using this editor, it can be integrated into any .NET project as a lightweight way to experiment with adding scripting support. Using the hosting ideas I presented before, an application written in C# could use IronRuby to allow users to write applications against their object model, or extend it at runtime. Here’s a small example of hosting this editor in Witty, an open-source Twitter client running on .NET:
While it is great that you can so easily add scripting into a .NET application, it ends up exposing the design deficiencies in the application being scripted. In Witty’s case, the Twitter class (T) is very good, but the Window class (U) isn’t in good shape, as there are a ton of methods on the type, and it’s unclear how they should be used to drive the UI. Jon Galloway wants to merge this into Witty, so hopefully some of these refactorings can be made to enable scripting better.
I extend this offer to all open-source .NET/Mono projects – if you want to improve your architecture and add scripting support, please let me know and I’ll help out.
It's worth noting that .NET 4.0, the next version of the .NET framework, C# supports a "dynamic" keyword which will let you call Ruby or Python (or any DLR language) just by using method calls.
Compatibility is really good at this point. We run the RubySpec test suite, passing at (85%) and the test suites from popular Ruby frameworks, including Rails, Rake, RSpec, and RubyGems, on every check-in, and can run pretty substantial Rails applications. Increasing compatibility bugs will definitely be the focus of the point releases approaching 1.0; mainly based on what you tell us needs fixing.
Performance is also in a very good place. This past version has pushed on the Ruby benchmark suite, and now we are >= 2x better than MRI on almost all benchmarks. Those numbers will be published on http://ironruby.info around the same time IronRuby 0.9 comes out. The above image shows that IronRuby (in blue) is normally significantly faster than MRI (in red), except for a handful of cases. The is not the end-all-be-all metric to measuring performance, but it’s nice to see IronRuby continuing to improve here.
In prior releases, Rails startup has gotten dramatically better, going from 80+ seconds in March to ~20 seconds now. Read more about Rails performance is the IronRuby 0.6 release.
Interesting IronRuby usages
Now that IronRuby is approaching 1.0, we're seeing very interesting usages of Ruby with .NET:
- AutoCAD scripting -- Kean Walmsley
- magic DSL for Windows UI frameworks -- Thibaut Barrère
- Automated conversion of an app written in an in-house language (lang runs on FORTRAN77) and MOTIF UI “to” IronRuby and WPF -- Robert Brotherus
- Point of Sale application based on WPF, IronRuby and FoxPro -- Nick Rickets
If you know of more interesting usages, please send them my way!
Thanks for reading this far! Keep an eye out on this blog and the ironruby website for the upcoming 0.9 release.