Yusuke Endoh, the release manager for Ruby 2.0, made several announcements: the immediate feature freeze for Ruby 2.0.0, the first preview release, and the targeted release date: February 24, 2013. February 24 also marks Ruby's 20th birthday, so it would be a fitting date for the 2.0 release.
A summary of new features can be found in Ruby's NEWS file, and also in their issue tracker. Of all the changes, Keyword Arguments and Refinements could have the biggest impact on Ruby programmers:
Keyword Arguments
Instead of just passing a hash as a method argument, Ruby 2.0 will include proper support for keyword arguments. Here's an excerpt from Ruby's own unit tests:
def f1(str: "foo", num: 424242) [str, num] end def test_f1 assert_equal(["foo", 424242], f1) assert_equal(["bar", 424242], f1(str: "bar")) assert_equal(["foo", 111111], f1(num: 111111)) assert_equal(["bar", 111111], f1(str: "bar", num: 111111)) assert_raise(ArgumentError) { f1(str: "bar", check: true) } assert_raise(ArgumentError) { f1("string") } end
Note that these will only work for arguments that have a default value. More examples of the new syntax and how it works with traditional arguments can be seen in Ruby's unit tests.
Refinements
Refinements aim to make monkey patching safer by reducing the scope where the patching is applied. In the following example posted by Matz, the / operator is only available on Fixnums after the MathN module has been included:
module MathN refine Fixnum do def /(other) quo(other) end end end class Foo using MathN def foo p 1 / 2 end end
Yehuda Katz wrote up a detailed blog post on how Refinements can be used in practice. Refinements are currently included in the Ruby 2.0 branch, but they might still get kicked out because of performance problems (see the original feature request for the discussion).
InfoQ had the chance to talk to Yusuke Endoh to learn more about Ruby 2.0. We asked him what he thinks will be the biggest changes for users:
A refinement is the most fundamental new feature to the language, which gives a new concept to Ruby's modularity. Many people can take advantage of the feature to replace the bad practice of "monkey-patching". Note that the feature is still evolving, say, unrefined itself yet. It will grow more mature in the future after we have more experience with it. (Of course, we will respect the compatibility as much as possible.)
A keyword argument is the most eye-catching feature. In fact, the feature is far from "the biggest"; it is just a syntactic sugar. But, from a practical perspective, it can be very helpful to make your code cleaner.
Enumerator#lazy is a long-time dream for lazy programmers, i.e., those familiar with functional programming. The feature serves as lazy evaluation for a list.
Module#prepend may be the most (implicitly) used feature. It replaces Rails' dirty "method_alias_chain" with a much tidier mechanism by using a module.
You may want to take a look at Akira Matsuda's presentation at RubyConf to learn these features in detail.
Of course, the performance has also much improved. This might be the most interesting change for those not interested in new features.
InfoQ: Will it be easier to upgrade from 1.9 to 2.0 than it was from 1.8 to 1.9?
We believe all "normal" programs will work without modification. In designing 2.0, we have taken considerable care in source compatibility with 1.9.
There are, however, some small changes. We think that they will cause no practical compatibility issue, but we could be wrong. If we know a problem before the official release, we are happy to reconsider them.
So, please try preview and RC releases and report anything you notice. We really appreciate your feedback.
InfoQ: Can you name some potential incompatibilities users might run into?
As mentioned above, there are indeed a few small incompatibilities. You can see them in the NEWS file. For example:
We would like to make a simple guidance about upgrade with the official 2.0.0 release, by accumulating feedback on preview and RC releases.
- Object#respond_to? returns false for protect methods by default.
- Kernel#system and #exec does not inherit non-standard file descriptor by default.
- Object#inspect does not call #to_s by default.
As Yusuke mentioned, performance has been improved. And to lower Ruby's memory usage, a new Bitmap Marking GC (InfoQ talked to its developer Narihiro Nakamura) will be included in the 2.0 release. If you want to learn more about how it works, take a look at this fantastic write up on Ruby garbage collection.
Here are some more interesting new features and important changes that will be part of Ruby 2.0:
- DTrace probes to profile applications at runtime
- Enumerable#lazy to lazily perform operations on an Enumerable
- Improved Regex library Onigmo that supports some new features introduced in Perl 5.10
- Method transplanting allows you to transplant module methods to other modules or classes
- Module#prepend to prepend a module so that prepended methods override already existing methods
- Object#respond_to? doesn't check for protected methods anymore
- HTML5 support in CGI
Download the Ruby 2.0.0-preview1 release and let us know what you think!