I'm pleased to announce a new release of 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
- Win32OLE support
- Rubyizing Generics
- Some more notable changes
- Bugs closed
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_scriptshas also been added to returns a dictionary that holds on loaded scripts and their Scopes, in-case you used
Kernel#requireto load a script, and need its Scope at a later time.
IronRuby#loaded_assembliesreturns 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#globalsreturns the current
ScriptRuntime.Globalsscope; 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.
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:
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[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.
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
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.