Behaviour change of String#gsub(pattern) {|m| ... } for ruby 1.9/ruby2?

String#gsub(pattern) {|m| … }

It really would be nice to get match data in ‘m’, but this would surely
break a lot of scripts. How about String#regsub, #regsub!, #resub,
#resub! ? What do others think?

···


dave

Hi,

···

In message “behaviour change of String#gsub(pattern) {|m| … } for ruby 1.9/ruby2?” on 03/11/20, David Garamond lists@zara.6.isreserved.com writes:

String#gsub(pattern) {|m| … }

It really would be nice to get match data in ‘m’, but this would surely
break a lot of scripts. How about String#regsub, #regsub!, #resub,
#resub! ? What do others think?

Sounds nice. The only reason for the current behavior is that sub
predates MatchData. But we have to define migration path.

						matz.

Is there an easy way for String#gsub (et al.) to check the arity of
the provided block?

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.

-austin

···

On Thu, 20 Nov 2003 20:57:58 +0900, Yukihiro Matsumoto wrote:

In message "behaviour change of String#gsub(pattern) {|m| … }

String#gsub(pattern) {|m| … }

It really would be nice to get match data in ‘m’, but this would
surely break a lot of scripts. How about String#regsub,
#regsub!, #resub, #resub! ? What do others think?
Sounds nice. The only reason for the current behavior is that sub
predates MatchData. But we have to define migration path.


austin ziegler * austin@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.11.20
* 10.18.43

Yukihiro Matsumoto wrote:

Hi,

Moin!

String#gsub(pattern) {|m| … }

It really would be nice to get match data in ‘m’, but this would surely
break a lot of scripts. How about String#regsub, #regsub!, #resub,
#resub! ? What do others think?

Sounds nice. The only reason for the current behavior is that sub
predates MatchData. But we have to define migration path.

I like this, because matz told me I shouldn’t be using $1 in the
gsub-block and there’s no way to not do so right now. :slight_smile:

Add a MatchData#to_str and it should work for most cases. We could give
a warning for cases where scripts would still be broken by this chance.

Regards,
Florian Gross

Is there an easy way for String#gsub (et al.) to check the arity of
the provided block?

svg% cat b.rb
#!/usr/bin/ruby
def a(&block)
   p block.arity
end

a {|x| }
a {|x, y| }
svg%

svg% b.rb
1
2
svg%

Guy Decoux

Hi –

Yukihiro Matsumoto wrote:

Hi,

Moin!

String#gsub(pattern) {|m| … }

It really would be nice to get match data in ‘m’, but this would surely
break a lot of scripts. How about String#regsub, #regsub!, #resub,
#resub! ? What do others think?

Sounds nice. The only reason for the current behavior is that sub
predates MatchData. But we have to define migration path.

I like this, because matz told me I shouldn’t be using $1 in the
gsub-block and there’s no way to not do so right now. :slight_smile:

I’ve also just noticed this:

irb(main):001:0> “abc”.gsub(/((x?)abc)/) {|n,m| p n, m}
“abc”
nil

as opposed to:

irb(main):002:0> /((x?)abc)/.match(“abc”).captures
=> [“abc”, “”]

which makes it hard to do, say, downcasing of a capture in #gsub,
without checking it for nil-ness or, as you say, using $1 and friends.

David

···

On Fri, 21 Nov 2003, Florian Gross wrote:


David A. Black
dblack@wobblini.net

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

···

Austin Ziegler austin@halostatue.ca 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.

I had actually done what you did, Guy, but I don’t know the C side of Ruby,
so I don’t know how easy it is.

I think that this is probably a good stab at a solution, though.

-austin

···

On Fri, 21 Nov 2003 00:31:05 +0900, ts wrote:

Is there an easy way for String#gsub (et al.) to check the arity of A>
the provided block?


austin ziegler * austin@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.11.20
* 11.31.12