== Migration issues between 1.8.x and 1.9

This page lists backward-incompatible changes between the 1.8.x serie of ruby and the current 1.9.

Unfortunately, this page is new and wasn't maintained during 1.9 development. Please contribute to help migrate to 1.9.

=== Inheritance evaluation order

class Base
def self.inherited(klass)
klass.instance_variable_set(:@x, :base)

Derived = do
@x = :derived
#ruby 1.8: @x => :base
#ruby 1.9: @x => :derived

See #4273 for more details

=== switch case

case foo
when x: bar


case foo
when x then bar

=== Date#to_s doesn't rely on locales anymore

If you where relying on Date#to_s to give you a certain output, it might change now.

ruby 1.8 was taking into account the system's locale, so that Date#to_s would change apparence depending on it.

TODO: find commit ID ?

=== Encoding issues

Ruby 1.9 now associates encoding type to every string it handles.
Since encodings can't always be converted without loosing information,
ruby might raise an exception on string concatenation, or if you try to
write in a file with a different encoding.

This is generally just unlocking an issue you already had in your application,
but that wasn't handled properly.


=== Hash#select returns a Hash

ruby 1.8:

{:a=>1}.select{|*x| p x; true}
[:a, 1]
=> [ [:a, 1] ]

ruby 1.9:

{:a=>1}.select{|*x| p x; true}
[:a, 1]
=> {:a=>1}

=== Block parameters a block-local

If you relied on the fact that block parameters override parent variables, it might be an issue, but in general you're better off with the new behavior.

ruby 1.8:

x = 3
=> 3
y = proc {|x|}
=> #Proc:0x0000000000000000@(irb):2
=> nil
=> 4

ruby 1.9:

x = 3
=> 3
y = proc{|x|}
=> #Proc:0x0000010109cb60@(irb):14
=> nil
=> 3

=== String is not Enumerable anymore

Since String is no longer an array of bytes, you may want to iterate on bytes or characters.

ruby 1.9:

NoMethodError: undefined method `each' for "foo":String
=> #<Enumerator: "foo":each_char>
=> #<Enumerator: "foo":bytes>

=== #Hash Iteration in Ruby 1.8 vs Ruby 1.9

This works in Ruby 1.8, Ruby 1.9.1 but does not work in Ruby 1.9.2

h = {'a' => 1, 'b' => 2, 'c' => 3}
p h
h.each_key do |k|
p k
if k == 'c'
h['d'] = 4
p h

This affects the dbi gem and so will affect all the postgresql users out there that work with Ruby ;/ - how do I set anchors in this page?

=== #Multilingualization (m17n) issues between Ruby 1.8 and Ruby 1.9

* String class
      o Ruby 1.8: Array of bytes
            + include Enumerable => String can be used like an Array)
            + 'String#[0]' returns ascii code 
      o Ruby 1.9: encoded characters (not Array but [] method is available)
            + String class behavior changes depending on the encoding
            + 'String#[0]' does not return ascii code (ex. use String#unpack('C*')[0], String.bytes.to_a[0])
            + not include Enumerable module (ex. String#each does not work)
            + we cannot use binary data (byte data) directly through String class
            + we have to set 'ascii-8bit' as an encoding for binary data 
* Magic comment
      o we have to write encoding (magic comment) in each script
      o '' cannot read binary file anymore (Ruby 1.8 can)
      o ex. instead of 's ="input.dat")' 

        s = open("input.dat","rb"){|f|}

* Careful points from 1.8 to 1.9 (encoding)
      * String#[0] does not return ascii code (this does not output an error, the behavior changes)
      * Put magic comment (encoding) if there are non-ascii characters in source code (in most of the cases, an error comes)
      * Pay attention to the encoding when we use String class, binary data, regular expression
      * We cannot use Enumerable methods for a String instance 

Also see:

=== subtle differences in dbi between Ruby 1.9.1 and Ruby 1.9.2

=== Gem compatibility

Not all rubygems are compatible with 1.9. is an effort to list all working gems, but I'm not sure if it's officially supported