What's to Like in Ruby 1.9

9:52 AM EDT Tuesday, April 29 2008

A few days ago, Charles Nutter asserted that "people are not flocking to Ruby 1.9 in droves". I would consider myself one of those people. When I thought about Ruby 1.9, I just assumed they were tweaking the syntax a little but mostly working on a VM that would make Ruby faster. Mainly though, Ruby 1.9 is an unstable, development release, so it's really just for playing around with it. The intent is for 1.9 to drive development for Ruby 2.0, and have people flock to Ruby 2.0 once that is ready for prime time.

Another factor is that up until today, I didn't really know much about what is planning on being added to Ruby 1.9. There is a complete list of changes in Ruby 1.9, but it wasn't until I came across a slideshow by Bruce Williams that covers some of the changes in Ruby 1.9 that I took the time to download, install and try out a few new features. So I thought I would put together a blog entry of 5 of my favorite changes:

  1. New Literal Syntax for Hashes

    {:foo => 1, :bar => "two"} now becomes {foo: 1, bar: "two"}. This is probably minor, but I really like it. It's a little bit cleaner, although I'm sure Obie will be sad to see the hash rocket go. Actually, I'm sure the hash rocket will still be supported, it will just become no longer idiomatic.

  2. New Proc literal

    But fear not Obie, we lose one operator, the hash rocket, but gain another, the proc rocket. You can now define a proc like this:

    double = ->(x) { x * 2 }
    puts double.(5) # => 10
    

    That can lead to some pretty crazy things, like this:

    p = ->(n, name="it", &block) {
        n.times{|i| block.call }
        puts "I did #{it} #{n} times"
    }
    
    
    p.(3) do |i| 
      puts "#{i} is #{i.even? ? 'not ': ''}odd"
    end
    
    
    p.(3, "foo") do |i| 
      puts "#{i} is #{i.even? ? 'not ': ''}odd"
    end
    

    The difference being that you can now have default values for arguments to a Proc and also you can pass a Block to a Proc. I could see this being used in metaprogramming. You could probably do a lot of things with this instead of things that get done using class_eval now.

    #Ruby 1.8
    class Foo
    end
    Foo.class_eval <<-CODE
      def bar(x,y=2)
        puts "x => \#{x}, y => \#{y}"
      end
    CODE      
    
    
    #Ruby 1.9
    class Foo
    end
    Foo.send(:define_method, :bar, ->(x, y=2) { 
      puts "x => #{x}, y => #{y}" 
    })
    

    Not sure yet if that would be better, I guess we'll see.

  3. Hashes preserve insert order

    Say goodbye to using 2D arrays just because you want things to be in a certain order. This is very convenient, but I was always under the impression that this is the way it was for performance reasons. I'd like to hear more about this. Is this one of those things where 80% of the time you don't care about that level of performance because your hash is relatively small and the convenience of preserving sort order is a better benefit? Is there some kind of FastHash class that can be used for cases where you don't care about ordering and better performance is needed? Or is the performance of the insertion-order Hash good enough for all cases?

  4. New Regular Expression Engine

    The Oniguruma regular expression engine is used in Ruby 1.9. This engine supports many advanced regular expression features. I once looked into directly porting the Perl Markdown code into Ruby but quickly found out that wasn't possible given the limitations of the Ruby 1.8 regular expression engine, so it's nice to see Ruby will have a regular expression engine that is on par with that of any other language.

  5. Object#tap and Symbol#to_proc

    I lumped these together into one because they are both kind of the same thing. These are two language level features that have become idiomatic Ruby because they have been added in Rails. The downside has been that if you are not in Rails, you either don't have these, or you have to define them to use them. Now that is a problem no more and they are just going to be part of Ruby. Symbol#to_proc you should recognize and Object#tap is the same thing as returning.

Posted in  | Tags Ruby

Comments Feed

1. Good article; I'm a big fan of 1.9 myself. I also don't think the number of people 'flocking' makes that big of a difference for an unstable version (I remember 1.7):

The 'hashrocket' use in Hash literals is [at least at this time] still supported, and you can even mix and match, although it's odd:
{ foo: 1, :bar => 2, baz: 3 }

# Posted By Bruce Williams on Tuesday, April 29 2008 at 11:28 EDT

2. Unless I am much mistaken, the hash rocket is neither deprecated nor un-idiomatic. The new syntax is sugar for a very specific kind of hash: the kind where all the keys are Symbols. Granted, this is a pretty common usage of Hash, especially in Rails. But hashes are still going to support keys of arbitrary types, for which the hash rocket remains necessary.

And thank goodness. You don't appreciate arbitrarily-keyed hashes until you work in a language without them, like Perl (strings only) or Python (immutables only). This is IMO one of the great unsung design choices of Ruby.

# Posted By Avdi on Tuesday, April 29 2008 at 01:29 EDT

3. Ahh....so that's what you meant by arbitrarily-keyed hashes. You mean hashes that can have an object of any type as the key. I agree, that is a nice feature. Even Java has that, so I guess I've been sort of taking that for granted.

But you are right, the hash rocket will still be needed for hashes with non-symbol keys, but also as you said, that won't be nearly as common. So it will still be supported, but won't be idiomatic for symbol-keyed hashes.

# Posted By Paul Barry on Tuesday, April 29 2008 at 03:29 EDT

Add a Comment