After complaining to our developers about using the old, <1.8’s => syntax in hashes, I was challenged by my ninja colleague Avi Tzurel to create a script that will convert all the old Ruby hash syntax to the new 1.9, beautiful colon notation.

I came up with this:

1
2
3
4
5
6
7
8
Dir['**/*.rb'].each { |f|
  s = open(f).read
  awesome_rx = /(?<!return)(?<!:)(?<!\w)(\s+):(\w+)\s*=>/
  count = s.scan(awesome_rx).length
  next if count.zero?
  s.gsub!(awesome_rx, '\1\2:')
  puts "#{count} replacements @ #{f}"
  open(f, 'w') { |b| b << s } }

The crazy negative lookbehinds ensures that nothing like

1
2
3
4
5
begin
   # ...
rescue Namespace::Exception => ex

end
1
2
3
def something
  return :x => 1, :y => 2
end

will get replaced. Turns out that after return you can only use the old syntax, or have curly brackets. Also, unfortunately, negative lookbehinds can’t contain Regexp inside them. So the multiple negative lookbehinds are like a big ‘or’.

Our really big project, with hundreds of .rb files, Gogobot, converted and is working great. Still afraid to do the final git push though ;)

Enjoy!

Comments