See if you can guess what this code will do before you run it in ruby.
upc = Proc.new {|m| $1.upcase}
puts "hello world".gsub(/([aeiou])/, &upc)
puts "hello world".gsub(/(\w)/, &upc)
def doit(str, re, blk)
puts str.gsub(re, &blk)
end
doit "hello world", /([aeiou])/, upc
doit "hello world", /(\w)/, upc
Now try running it in JRuby. Whoa.
D? huh?
Oh, right. Scope binding. Yay.
out of curiosity, what does it do in JRuby? works “correctly”? :)
rubinius passed the test ;)
I really liked this post. Thanks.
Looks like another good reason to not use perl style global variables changing upc = Proc.new {|m| $1.upcase} to upc = Proc.new {|m| m.upcase} works as expected
Yargh, I was bitten by this about a year ago…it’s still the nastiest thing I’ve found in Ruby. When researching it, I found this Ruby-talk thread useful:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/79283
Note that Matz advices that you avoid the perl-style variables.
When I ran into this, I was trying (ill-advisedly) to wrap all the methods of String class in something in Rails, and Rails uses (or at least did use) those globals, blowing everything to pieces.