Ruby 1.9 porting tips/notes

  1. formal argument cannot be an instance variable:
    In ruby1.8 it’s possible to use an instance variable as a block argument:

    class Foo
      attr_accessor :bar
      def test
         [1,2,3].each {|@bar| }
         # @bar will be 3 here

    This no longer works in ruby1.9, you as it always creates a new local variable block argument. The equivalent in ruby1.9:

    class Foo
      attr_accessor :bar
      def test
         [1,2,3].each {|bar| @bar=bar }
         # @bar will be 3 here
  2. warning: shadowing outer local variable:
    In ruby1.9 the block arguments are always local to block, in ruby1.8 if there’s an existing variable with the same name, the block parameter will use that one:  

    i = 0
    [1,2,3].each {|i| }
    puts i

    This will print 0 in ruby1.9, as the variables named i inside/outside the block are different, and 3 in ruby1.8, as here the block reuses the outside variable i.

    As with most warning, this warning doesn’t means that your code is incorrect, only that it might be incorrect.
    For example the code bellow works the same in ruby1.9 and 1.8:

    options = options.inject({}) do |options,pair|
      options[pair.first.to_sym] = pair.last.to_sym; options

    It still makes sense to rewrite the above code just to supress warnings.

    Note: You should set RUBYOPT to -w, or start your program with ruby -w, for this warning to show up

  3. syntax error, unexpected ‘,’, expecting tASSOC
    ruby1.8 supports , in hash definition, in 1.9 you have to use =>.  

    So the following valid ruby1.8:


    has to be rewritten in ruby1.9:

    {"a" => "b"}
  4. invalid multibyte char:
    the default encoding in ruby 1.9 for files is US-ASCII, if you have a non ASCII character in your text file you have to specify the encoding of the source code. You can do it by adding the following line to your ruby file:  

    # coding:utf-8
  5. NoMethodError: undefined method `to_a’ for “…”:String:
    In Ruby1.8 the String class has a to_a method, so in ruby1.8 you can write:

    lines = string.to_a

    The equivalent in ruby1.9 is:

    lines = string.lines.to_a
    # chars = string.chars.to_a # to get array of chars
    # bytes = string.bytes.to_a # to get array of bytes

    The issue with this solution, is that the ruby1.9 solution is not compatible with ruby1.8.

    Some ideas for a ruby1.9 and ruby1.8 compatible solution:

    The first one is to add a lines method to the String, so you can use the ruby1.9 syntax:

    unless String.method_defined?(:lines) then
      class String
        def lines

    The downside is that this lines method is not 100% compatible with ruby1.9 String#lines – for example string.lines(“\n\r”) won’t work. 

    The second one is to check at each call whether it has the lines method:

    if str.respond_to?(:lines) then
      lines = string.lines.to_a
      lines = string.to_a
  6. unexpected ‘:’, expecting keyword_then or ‘,’ or ‘;’ or ‘\n’:
    case or if with : instead of then  

    Ruby1.8 allows the use of : shortcut instead of then in if and case expressions. In Ruby1.9 this is no more allowed.

    case 'test'
      when 'test': print 'OK'

    In ruby1.9 you’ll get a syntax error, so you have to replace the ‘:’ with ‘then’

    case 'test'
      when 'test' then print 'OK'
  7. no such file to load — base64:
    require "base64": ruby 1.9 ships without base64. You should use Array#pack, unpack  

     require 'base64'
     enc = Base64.encode64('Send reinforcements')
     plain = Base64.decode64(enc)

    In ruby1.9 you can write:

    enc = ['Send reinforcements'].pack( 'm' )
    plain = enc.unpack( 'm' )[0]
  8. ‘struct RString’ has no member named ‘ptr’
    ‘struct RString’ has no member named ‘len’:
    In ruby1.9 for the RString in C extensions was changed because of optimization, you should use the RSTRING_LEN, RSTRING_PTR macros instead of directly accessing the len, ptr members.  

    len = RSTRING(foo)->len
    ptr = RSTRING(foo)->ptr

    Should be changed to

    len = RSTRING_LEN(foo);
    ptr = RSTRING_PTR(foo);
  9. .methods changed from Strings to Symbols
    The contents of the methods array was changed from String to Symbol, so if you were doing something like this in ruby1.8:


    The ruby1.9 version is:


    And the following works in ruby1.8 and 1.9:

  10. TypeError: cannot assign nil; use Hash#delete instead
    In ruby1.8 you can remove an environment variable by setting it to nil.
    In ruby1.9 use the delete method instead:


Related link:


4 Responses to Ruby 1.9 porting tips/notes

  1. Nikos D. says:

    Migrating to Ruby 1.9 (YARV): Posts you have to re…

    So, you are reading everywhere that Ruby 1.9 is faster than 1.8 (even I say so! 😀 ) and you want to give it a try or even port your existing code to it. Where should you start from?…

  2. […] Заметили костыль в виде # coding:utf-8? Он и будет заниматься тем, что все символы будут корректно обрабатываться. Немножко не так просто, как хотелось бы, но уже что-то 🙂 Выполнение ruby18 test-unicode.rb выдаст нам следующую лабуду: 67 131 [“320”, “240”, “321”, “203”, “320”, “261”, “320”, “270”, ” “, “-“, ” “, “320”, “276”, “321”, “202”, “320”, “273”, “320”, “270”, “321”, “207”, “320”, “275”, “321”, “213”, “320”, “271”, ” “, “321”, “217”, “320”, “267”, “321”, “213”, “320”, “272”, ” “, “320”, “262”, “321”, “213”, “321”, “201”, “320”, “276”, “320”, “272”, “320”, “276”, “320”, “263”, “320”, “276”, ” “, “321”, “203”, “321”, “200”, “320”, “276”, “320”, “262”, “320”, “275”, “321”, “217”, “!”] Запуск же свежесобранного ruby19 test-unicode.rb покажет следующее: 37 и [“Р”, “у”, “б”, “и”, ” “, “-“, ” “, “о”, “т”, “л”, “и”, “ч”, “н”, “ы”, “й”, ” “, “я”, “з”, “ы”, “к”, ” “, “в”, “ы”, “с”, “о”, “к”, “о”, “г”, “о”, ” “, “у”, “р”, “о”, “в”, “н”, “я”, “!”] Что ж, куда лучше, не правда ли? 🙂 Очень советую тем, кто ищет что изучить, попробовать ruby, будете приятно удивлены элегантностью и гибкостью 😉 p.s.: заметки по портированию с 1.8 на 1.9 (англ.) […]

  3. Kevin H. says:

    The multibyte char comment line should read:

    # encoding:utf-8


    # coding:utf-8

%d bloggers like this: