IronRuby 0.9 Released!

02 Aug 2009

ir-logo-white

I'm pleased to announce a new release of IronRuby: 0.9!

Download IronRuby 0.9

You can also get the source code for this release

It’s been a long ride since IronRuby was announced at MIX ‘07, but now all eyes are 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.

Though IronRuby is breaking away from it’s conference-driven development schedule, this release comes only a week after OSCON 2009 where I talked about using IronRuby with Mono and Moonlight, and scripting open source apps.

What's in the Release?

Library performance was a big focus for this release; basically going though the Ruby Benchmark suite and making sure any obvious slowness was fixed. As I said in my previous post about OSCON, IronRuby is approximately 2x faster than MRI when running the benchmark suite, but in the near future a complete evaluation of IronRuby’s performance will be done and published on the website.

Antonio Cangiano has already published benchmark results between IronRuby 0.9 and Ruby 1.8.6, and things look really good for IronRuby.

On the compatibility front, the Win32OLE Ruby library is now available in IronRuby. This builds on top of IronRuby’s existing COM interop from version 0.5, letting you script any Windows component/application that exposes a COM interface. Though it hasn’t been fully tested yet, this will make things like Watir work on IronRuby.

Lastly, there have been interop improvements with .NET, most notably making Generic types more friendly to all the crazy things Ruby can do to them, and also with other DLR languages, making it really easy to call IronPython from IronRuby.

For more detailed information, please see the CHANGELOG (which includes all commit messages for the release ... not just "syncing to head of tfs")

Want to find out more about the release? Read on:

Calling Python code from Ruby

In an effort to allow Ruby to call Python code easily, IronRuby provides a way to importing files of other DLR languages, giving you access to the DLR scope. Here's a basic usage:

IronRuby#require(path), load(path) allow you to include script files, just like Kernel#require, #load except that they execute the given script against a new Scope and return it, instead of just returning true/false/nil. If the target is an assembly they return the loaded assembly. Keep in mind you can still use Kernel#require, #load to use other language's script files, but if the language requires you obtain an object representing that file (in Python it's called a module) you'll have to get it elsewhere (see below).

There are other methods to help you use other languages from Ruby:

  • IronRuby#loaded_scripts has also been added to returns a dictionary that holds on loaded scripts and their Scopes, in-case you used Kernel#require to load a script, and need its Scope at a later time.
  • IronRuby#loaded_assemblies returns an array of assemblies already loaded in the current runtime; though this isn’t needed for DLR language interop it makes sense to include along with IronRuby#loaded_scripts.
  • IronRuby#globals returns the current ScriptRuntime.Globals scope; this allows you to easily use Python files and work with the modules they define.

Keep in mind these concepts don’t only apply to Python; they can be used with any language that uses first-class scopes.

Win32OLE support

Since IronRuby 0.1 was released we’ve said Win32OLE was not going to be supported, due to the lack of general COM support in the DLR. However, when the DLR implemented a COM binder for the new dynamic feature in C# 4.0, this allowed IronRuby and IronPython to easily implement COM support. IronRuby 0.5 had this support, but in this release we provided win32ole.rb to implement Ruby’s Win32OLE API. Here’s a simple automation example which opens Excel, adds some data, generates a chart, and rotates the chart. taken from the Ruby Pragmatic Programmer’s Guide (aka. the pickaxe book), which now works in IronRuby:

Rubyizing Generics

Note: this feature didn’t make it into 0.9, but it is in the sources and will be part of 0.9.1

IronRuby has great .NET framework integration, so code written with a CLI-based language (C#, VB, F#) can be called from IronRuby, without it feeling like interop. As we work towards a stable 1.0 release and this integration continues to be polished; in this release we most notably made working with generics a bit friendlier to Ruby.

The first improvement has to do with re-opening a generic class. In the past you couldn’t just re-open a generic class and assume anything you added to it would be found on other versions of that generic class (eg. adding methods to List[] wouldn’t have them show up on List[String] and List[Fixnum]). Now the Ruby class corresponding to the CLR generic type definition is a super-class of all instantiations of that type, making this possible:

There's a much more usability improvements to generics and .NET interop in general in this release, so either take a look at the CHANGELOG or keep an eye on the .NET documentation.

Some more notable changes:
  • Fix to Module#autoload so it doesn’t squash an existing constant
  • Fix parsing of YAML time strings
  • Replace DLR closures by a Ruby-specific implementation for performance
  • Implement StringIO#ungetc – used in ActiveSuppor
  • Re-implements “tr”, “tr!”, “tr_s”, “tr_s!”. The new implementation is almost 12x faster.
  • Reimplements “join” to achieve better perf.
  • Change ComBinder class to internal.
  • Improves the ExpressionVisitor API
  • Improves implementation of RubyArray. A loop doing Array#shift is not shifting the entire array content left every iteration.
  • Add hosting of IronPython to hosting tutorial
  • Implements interpretation of coalescing expression
  • Implements Kernel#rand, Kernel#srand.
  • Improves scope allocation perf.
  • ironruby tutorial in Silverlight
  • More fixes to win32ole to get the ADO DBI driver working
  • String, Array, and Bignum fixes (thanks Daniele Allessandri!)
  • Explicit x64 support with ir64.exe, and force ir.exe to run in a 32bit process on a 64bit OS.
  • Implements basic debug views for classes that implement IRubyObject

For more details, see the CHANGELOG.

Bugs closed

Here are all 26 bugs closed since the last release (2009-07-02). You can see more information about each one on CodePlex.

1841 	Rubygems Test Failures in 'hash'
1506 	-X:PrivateBinding does not enable referring to classes that have internal visibility
1533 	Unverifiable code generated by mspec :lang
1678 	ArgumentError when calling System.String..ctor(Char[], int, int)
1211 	Adding a random object to Time which responds to to_f
910 	YAML does not properly deserialize Time values.
1626 	Rubygems failures
964 	overriding unsafe methods
1537 	rand doesn't work collectly
468 	Better error message for running ir.exe on pre-.Net 2.0 SP1
1787 	All-caps .NET method names are mangled strangely
1521 	Access is allowed to internal fields
1502 	alias_method fails for :do
821 	File.expand_path does not support a line number after filename
1509 	Proc.to_s should include line number where the block was declared
1501 	WinForms broken
1400 	$? is not always Process::Status
1345 	load_assembly() should work
1344 	System.Action.new does not work
1306 	Cannot call CLR constructor of builtin type
1184 	public(:foo) does not work correctly for mixed-in methods
1060 	visibility of send :define_method
917 	Passing a Ruby array to a .NET method that expects an IEnumerable derivative fails with GetEnumerator call
783 	Assert in SetMethodBasesNoLock when calling #== on Ruby class inheriting from CLR class which overrides Equals
761 	Wrong behavior when calling redefined methods on object instances
1470 	Can't call the BigIntegerOverload of a method with a DefaultProtocol Attribute on the BigInteger attribute
Enjoy!

Please test out IronRuby 0.9 and let us know if you have any issues. We hope you enjoy this release! Please submit issues to CodePlex and help prioritize features for 1.0.

Technorati Tags: ,,
comments powered by Disqus