New Ruby 1.9 Features, Tips & Tricks

Ruby 1.9 packs in a lot of new and improved features at all levels: it introduces a few new syntax constructs, the built-in libraries have been updated with hundreds of new methods and classes, it adds language level support for characters encodings, it ships with an entirely new virtual machine, and the list goes on. If you haven't already, you should seriously consider upgrading to Ruby 1.9 as it is a definite step up from the previous versions in all respects.

For the most part, you could upgrade from Ruby 1.8.x and remain blissfully unaware of the many updates and improvements within the language - but what fun would that be? For the curious, Ruby 1.9 Pickaxe is probably the single best resource to get yourself up to speed. To give you a flavor, below is a list of my favorite 30 tips, tricks and features - feel free to clone the gist and add your own!

New Ruby 1.9 Features, Tips & Tricks

def tip(msg); puts; puts msg; puts "-"*100; end

# 30 Ruby 1.9 Tips, Tricks & Features:
# http://www.igvita.com/2011/02/03/new-ruby-19-features-tips-tricks/

tip "Upgrading to Ruby 1.9 is simple: rvm install 1.9.2 && rvm --default 1.9.2"

tip "Ruby 1.9 supports named captures in regular expressions!"
  p "hello 2011!".match(/(?<year>\d+)/)[:year]  # => "2011"

tip "Ruby 1.9 uses Oniguruma as a new regex engine, and @pragprog has a fantastic (and free!) PDF on it: http://bit.ly/hIzvOi"

tip "Ruby 1.9 allows default arguments at the beginning of a method!"
  def f(a=1, b); p [a,b]; end;
  p f(2) # => [1, 2]

tip "Ruby 1.9 changed #to_s to use Object#inspect by default!"
  puts({a:1, b:[2,3]}.to_s) # => {:a=>1, :b=>[2, 3]}

tip "Ruby 1.9 added Hash#assoc, which returns a two element array [key, hsh[key]]!"
  p({a: 1, b: 2}.assoc(:b)) # => [:b, 2]

tip "Ruby 1.9 allows splat argument anywhere in a method's parameter list"
  def a(a,*b,c); p [a,b,c]; end
  p a(1,2,3,4) # => [1, [2, 3], 4]

tip "Ruby 1.9 allows matching regular expressions against a symbol!"
  p :ruby_symbol.match(/symbol/) # => 5

tip "Ruby 1.9 supports new & more compact hash syntax for symbol keys! "
  p({a:1, b:2}) # => {:a=>1, :b=>2}

tip "Ruby 1.9 supports new 'stabby proc' syntax!"
  f = -> a,b { p [a,b] }
  p f.call(1,2) # => [1, 2]

tip "Ruby 1.9 hashes preserve the insertion order of elements! for the curious: http://bit.ly/e0oEun"
  p({a:1, b:2}) # => {:a=>1, :b=>2}

tip "Ruby 1.9 supports 4 ways to call a proc!"
  f =->n {[:hello, n]}
  p f[:ruby]       # => [:hello, :ruby]
  p f.call(:ruby)  # => [:hello, :ruby]
  p f.(:ruby)      # => [:hello, :ruby]
  p f === :ruby    # => [:hello, :ruby]

tip "Ruby 1.9 no longer supports .each on a string! instead, use: .chars, .bytes, .lines, .each_char, etc..."

tip "Ruby 1.9 allows default parameters in procs & lambdas!"
  f =-> a,b=1,*c { p [a,b,c] }
  p f.call(1)   # => [1, 1, []]
  p f.(1,2)     # => [1, 2, []]
  p f[1,2,3]    # => [1, 2, [3]]

tip "Ruby 1.9 added ObjectSpace.count_objects method which returns a hash of types+counts of objects in current process"

tip "Ruby 1.9 added each_with_object to Enumerable!"
  p (1..10).each_with_object([]) {|i, a| a << i*2 } # => [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

tip "Ruby 1.9 added Object#public_send, which will raise an error on messages to private methods!"

tip "Ruby 1.9 added Enumerable#sample(n), which returns n random elements!"
  p [1,2,3,4].sample(2)  # => [2, 3]

tip "Ruby 1.9 added Kernel#define_singleton_method"
  c = 'cat'; c.define_singleton_method(:hi) { p 'hi' };
  p c.hi  # => "hi"

tip "Ruby 1.9 added support for block-local variables!"
  v = 'ruby'; [1,9].map {|val; v| v = val }
  p v # => "ruby"

tip "Ruby 1.9 blocks now allow blocks as parameters!"
  b = -> v, &blk { p [v, blk.call] }
  p b.call(:a) { :b } # => [:a, :b]

tip "Ruby 1.9 threads are now mapped (1:1) to OS threads! ex: gdb -p [ruby PID], info threads - yes, there is still a GIL."

tip "Ruby 1.9 added Process.daemon to put current process into background, see docs @ http://bit.ly/hY55HK"

tip "Ruby 1.9 ships with JSON support: require 'json' + Kernel#j, Kernel#jj"
  require 'json'
  h = {a:1,b:2}
  j(h); jj(h)

tip "Ruby 1.9 allows you to set a default input encoding with a magic comment (http://bit.ly/dRhgHy) ex: # encoding: UTF-8"

tip "Ruby 1.9 added GC.count & GC::Profiler (http://bit.ly/fhPsiJ)"
  GC::Profiler.enable; GC.start; puts GC::Profiler.result

tip "Ruby 1.9 allows you to introspect YARV bytecode!"
  puts RubyVM::InstructionSequence.compile('a = 1; p 1 + a').disassemble

tip "Ruby 1.9 shipped with MiniTest, a successor to Test::Unit! worth a look: http://bit.ly/ea2xmP"

tip "Ruby 1.9 regular expressions allow you to invoke subpatterns (recursively, even) with \g<name>! http://bit.ly/ikgT2t"

tip "Ruby 1.9 added Process.spawn which will execute cmd in subshell"
  pid = spawn('echo hello')
  p Process::waitpid2(pid)  # => [62777, #<Process::Status: pid 62777 exit 0>]

tip "Ruby 1.9 added Enumerable.reduce, which is equivalent to Enumerable.inject"
  p [1,2,3].reduce(:+)  # => 6

In case you can't preview the gist: direct link, or see the raw file.


Ilya Grigorik

Ilya Grigorik is a web performance engineer and developer advocate at Google, where his focus is on making the web fast and driving adoption of performance best practices at Google and beyond.