From: sabbyxtabby@... (Sabby and Tabby) Date: 2003-11-22T21:47:12+09:00 Subject: Re: behaviour change of String#gsub(pattern) {|m| ... } for ruby 1.9/ruby2? Austin Ziegler wrote: > String#gsub(pattern) { |m, md| ... } > yields match string and matchdata > > String#gsub(pattern) { |m| ... } > yields match string only > > That would break the least amount of code. Lightly tested, seems to work: class String alias _sub sub alias _sub! sub! def sub(*a, &b) b ? _sub(*a) {|s| b.arity == 2 ? b[s, $~] : b[s]} : _sub(*a) end def sub!(*a, &b) s = sub(*a, &b) s == self ? nil : replace(s) end end Not portable, fragile, sometimes works: module Kernel alias _sub sub alias _sub! sub! def sub(*a, &b) $a, $b, $c = a, b, "" set_trace_func(proc {|*x| if x[0] == 'return' eval("$c.replace($_.sub(*$a, &$b))", x[4]) set_trace_func(nil) end }) $c end def sub!(*a, &b) $a, $b = a, b r, w = IO.pipe fork or return set_trace_func(proc {|*x| w.puts(eval("$_.sub!(*$a, &$b).inspect", x[4])) exit! }) Process.wait $c = eval(r.readline) or return set_trace_func(proc {|*x| if x[0] == 'return' eval("$_.replace($c)", x[4]) set_trace_func(nil) end }) $c end end