January 16th, 2009
I’m happy to see that my recent 10 things to be aware of in moving to Ruby 19 article has proven helpful to lots of people. This article is a follow-up.
The goal of the article was to point out 1.9 features and changes that might cause your existing code not to run correctly, or not to run at all. I went a bit soft, though: two of the original ten (hashes being ordered and the changes in method-argument syntax) weren’t really things that might break your 1.8 code.
So I feel I owe the world two more code-breaking 1.9 features! And they’re here, along with a bonus one.
But first, some links
The denizens of ruby-talk have provided lots of helpful ideas and feedback. James Edward Gray II and others mentioned M17N, a topic on which I defer to the more expert among us, especially James who has written a multi-part M17N guide. He’s going to be expanding it to include 1.9 encoding, so keep an eye on it.
Brian Candler suggested that people might be interested in the presentation by me and Dave Thomas at RubyConf 2008 on Ruby 1.9: What to Expect. We cover some pitfalls but also some new, non-pitfall features you might want to know about.
If you’re interested in Ruby 1.9 generally, you might be interested in my forthcoming book The Well-Grounded Rubyist, which is a fully revised, revamped, “Ruby only” second incarnation of my 2006 book Ruby for Rails.
Apologies to anyone I’ve failed to credit, and thanks to all for the feedback.
And with that, here are the pitfalls! (Speaking of pitfalls, I think I’ve remembered all the <pre> tags this time….)
String indexing behavior has changed
(Thanks to Michael Fellinger and Robert Dober)
In Ruby 1.8, indexing strings with
, as in
you an ASCII code:
>> "string" => 105
In order to get a one-character-long substring, you have to provide a length:
>> "string"[3,1] => "i"
In Ruby 1.9, the indexing operation gives you a character.
>> "string" => "i"
Also, kind of along the same lines, the ?-notation now gives a character rather than a code. In 1.8:
>> ?a => 97
and in 1.9:
>> ?a => "a"
if-conditions can no longer end with a colon
In 1.8 you can do this:
if x: puts "Yes!" end
In 1.9, you can’t use that colon any more. The same is true of when clauses in case statements. This will not parse in 1.9:
case x when 1: "yes!" end
Bonus thing! No more default to_a
In 1.9 you cannot assume that every object has a
You’ve probably seen warnings about this in 1.8, and the day of
reckoning has now arrived.
>> "abc".to_a NoMethodError: undefined method `to_a' for "abc":String
You can use the Array method to turn anything into an array. If it’s
an array already, it returns the object itself (not a copy). If it’s
anything else, it tries to run
to_a on it (in that order),
and if those aren’t available, it just wraps it in an array.
Array isn’t new, but we’re likely to be using it a lot more
now that there’s no default