To answer a question on RubyTalk the other day, I had to reference Mauricio Fernandez’s nicely compiled list of Changes in Ruby 1.9. While I was there I took another walk through the whole thing.
There are of course some features I *don’t* like.
a = ->(b,c){ b + c }
a.call(1,2) # => 3
But there are quite a few that I do, and here I’ve listed ten I think will totally rock. I use Mauricio’s examples, so all credit goes to him. Also, this article is from February, so if you find any features below that have changed, shout and I’ll update.
1. Enumerator is in core and more tightly integrated
This means all your enumerable objects can return Enumerators without a require, and also avoids some use of enum_for
a = 4.times
a = a.each
a.inject{|s,x| s+x} # => 6
I had to cross my eyes a couple times to understand what was going on there, but I came to the conclusion that ultimately, that is going to rock.
2. Enumerator#with_index
I think most people will at some point be look to do a map_with_index, and this brings you quite close:
[1,2,3,4,5,6].map.with_index {|x,i|[2,5].include?(i) ? x : x*2} #=> [2, 4, 3, 8, 10, 6]
3. Better Array#to_s and Hash#to_s
[1,2,3,4].to_s # => "[1, 2, 3, 4]"
{1,2,3,4}.to_s # => "{1=>2, 3=>4}"
IIRC, puts will still do its magic when used on Arrays.
4. Method#receiver and Method#owner
class A; def foo; end end a = A.new a.method(:foo).receiver # => #<A:0xa7c9f6d8> class A; def foo; end end a = A.new a.method(:foo).owner # => A
I’m sure we’ll find something evil to do with that. :)
5. Process.daemon
Process.daemon() => fixnum Process.daemon(nochdir=nil,noclose=nil) => fixnum
By default, this will detach the process and change the working dir to the root. It’ll also redirect all output to /dev/null. Sounds like this will be a *nix only feature but having built in support for daemonizing scripts should be great.
6. Blocks can take block argument
define_method(:foo){|&b| b.call(bar)}
Hooray, a simultaneous win for higher order procedures and metaprogramming goodness!
7. Block arguments are always local
a = 1
10.times{|a| } # !> shadowing outer local variable - a
a # => 1
Compared to the nasty behaviour on 1.8:
a = 1
10.times { |a| }
a # => 9
8. New literal Hash syntax
This is going to be great for making fake named arguments look even prettier
{ a: 1, b: 2 }
is now equivalent to:
{ :a => 1, :b => 2 }
which means you could easily do something like:
foo(a: 1, b: 2)
9. Class variables not inherited
Slightly weakening the case against them…
10. BasicObject
A lot of times, you want a minimalist object. There have been plenty of hacks to show how to construct one in Ruby 1.8, but we’ll get one for free in 1.9
BasicObject.instance_methods # => ["__send__", "funcall", "__id__", "==", "send", "respond_to?", "equal?", "object_id"] Object.ancestors # => [Object, Kernel, BasicObject]
Honorable Mentions
Enumerable#group_by looks like it rocks. Symbol#to_proc wasn’t mentioned here but it’s handy (lets you do something.map(&:some_attr)). Also, the best damn Regex engine ever, Oniguruma, is built into Ruby 1.9
I wonder if the core team is still on schedule for a Christmas release…. Should be interesting to see how people make use of all this new stuff.


Just a quick note: I backported the new enumerator stuff to 1.8. See http://flgr.0x42.net/code/future-enumerator.rb
Oh, and "a = a.each" does nothing... right?
@Florian
I gotta check out the backport, sweet.
I think you're right about "a = a.each", I think it just returns self.
From that list #owner and #receiver really catch my attention. I've found a similar feature in Javascript (caller, callee) to be useful at times. And yes... EVIL.
The hash syntax gets a big Yay from me. Less verbose and visually more compact. I think more readable all round. Using it to cheat named parameters is awesome!
ruby hash going json? neat..
@choonkeat,
It's also just an optional syntax, so you can still use the old way too. :)
External iterators - ick.
Mandatory arguments after optional arguments - ick.
The "&:" proc passing syntax - ick.
The keyword argument syntax - ick.
p6meter++ ;)
Daniel:
Enumerator is not an external iterator. See the generator standard library for that.
Enumerator is used to switch which method is considered each(), so you can combine Enumerable iterators. For example, a different way to do map_with_index() in Ruby 1.9 than what Greg showed is:
...each_with_index.map { |e, i| ... }
Here I am switching the normal each() iterator out for each_with_index() and then calling map() normally.
James Edward Gray II
JEG2,
Ok, but I still don't like it, and I think it will only make programs more difficult to read and debug, especially for the newbs. I think it's misguided.
@Daniel
That kind of surprises me. I feel like Enumerator is a godsend. :)
Gregory,
I guess I just don't see what problem it solves that a custom definition and/or Object#extend doesn't already solve, and in a less obscure way.
Sweet. Nice summary!
@Aria,
Thanks!
@Daniel,
I'd love to see an ORA blog post of how you can elegantly live without Enumerator for the tasks it solves. If nothing else, it'd serve as a good way to explain what tasks it does solve! :)
Is it just me or Ruby syntax is VERY confusing to read :(
I really like Rails concepts, and I want to learn Ruby. But it's syntax always discourages me. I'm afraid Ruby syntax readability will make maintenance of my applications in the future troublesome ...
@EricL,
That's actually somewhat surprising to hear. Most people find Ruby fairly readable. Let me say however that the code above is *not* a good place to start. Except for a handful of features there, most of that stuff is highly advanced functionality, and would be quite confusing if you didn't already have a strong grasp of the language.
What programming background are you coming from? Depending on the languages you already know, I can maybe point you at some helpful resources / books.