Lambda with $1 fails as gsub block


#1

I came across this problem:

def meth(replace)
“>x”.gsub(%r!(\W)x!, &replace)
end

replace = lambda { |match|
puts “$1 is #{$1.inspect}”
}

“>x”.gsub(%r!(\W)x!, &replace) # => $1 is “>”

“” =~ %r!! # reset $1

meth(replace) # => $1 is nil

Apparently $1 is bound in a peculiar way:

http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/e24a19e6ea75e5de/0211d0b304cbbad0?hl=enÓd0b304cbbad0

Matz suggested that the MatchData could have been passed to the block
for convenience, however it looks more like a necessity, as I don’t see
a solution short of rewriting gsub.

This suggests that for 1.9, MatchData should be passed as an optional
second argument to the block. Yes?


#2

Mike G. wrote:

I came across this problem:

def meth(replace)
“>x”.gsub(%r!(\W)x!, &replace)
end

replace = lambda { |match|
puts “$1 is #{$1.inspect}”
}

“>x”.gsub(%r!(\W)x!, &replace) # => $1 is “>”

“” =~ %r!! # reset $1

meth(replace) # => $1 is nil

Apparently $1 is bound in a peculiar way:

Interesting issue. A work-around:
module MDGsub
def md_gsub(pattern)
gsub(pattern) { yield($~) }
end
end
class String
include MDGsub
end

block = proc { |md| p [md.string, *md.captures] }
“>x”.md_gsub(%r!(\W)x!, &block) # -> [">x", “>”]

I hope that helps for the moment.

Regards
Stefan


#3

Mike G. wrote:

Matz suggested that the MatchData could have been passed to the block
for convenience, however it looks more like a necessity, as I don’t see
a solution short of rewriting gsub.

Here’s a solution:

def meth(replace)
“>x”.gsub(%r!(\W)x!) { |match| replace[$~] }
end

replace = lambda { |match|
puts “match is #{match.inspect}”
puts “match[1] is #{match[1].inspect}”
}

meth(replace) # => match[1] is “>”


#4

On Thu, Dec 11, 2008 at 12:18 AM, Mike G. removed_email_address@domain.invalid
wrote:

Apparently $1 is bound in a peculiar way:
Not really, it somehow the proc object that is evaluated “first”
def meth(replace)
“>x”.gsub(%r!(\W)x!)do
puts “$1 is #{$1.inspect}”
end
end
and
def meth(replace)
“>x”.gsub(%r!(\W)x!, &replace)
p $1
end

work as expected

You will clearly see what I mean with the following example

def meth(replace)
“>x”.gsub(%r!(\W)x!, &replace)
end

replace = lambda { |match|
puts “last_match is #{Regexp.last_match.inspect}”
}
which produces

last_match is #<MatchData “”>

Interesting stuff
Robert

Posted via http://www.ruby-forum.com/.


Il computer non è una macchina intelligente che aiuta le persone
stupide, anzi, è una macchina stupida che funziona solo nelle mani
delle persone intelligenti.
Computers are not smart to help stupid people, rather they are stupid
and will work only if taken care of by smart people.

Umberto Eco