# Lambda with $1 fails as gsub block

**URL:** <https://www.ruby-forum.com/t/lambda-with-1-fails-as-gsub-block/155359>\
**Category:** Ruby\
**Created:** [December 11, 2008, 12:25am UTC](https://www.ruby-forum.com/t/lambda-with-1-fails-as-gsub-block/155359 "2008-12-11T00:25:25Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![random52k](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@random52k](https://www.ruby-forum.com/u/random52k)\
**Post date:** [December 11, 2008, 12:25am UTC](https://www.ruby-forum.com/t/lambda-with-1-fails-as-gsub-block/155359/1 "2008-12-11T00:25:25Z")

</div>

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](http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/e24a19e6ea75e5de/0211d0b304cbbad0?hl=en%C3%93d0b304cbbad0)

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?

---

<div class="post-metadata">

**Author:** ![random52k](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@random52k](https://www.ruby-forum.com/u/random52k)\
**Post date:** [December 11, 2008, 9:51am UTC](https://www.ruby-forum.com/t/lambda-with-1-fails-as-gsub-block/155359/2 "2008-12-11T09:51:37Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![random52k](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@random52k](https://www.ruby-forum.com/u/random52k)\
**Post date:** [December 11, 2008, 9:57am UTC](https://www.ruby-forum.com/t/lambda-with-1-fails-as-gsub-block/155359/3 "2008-12-11T09:57:40Z")

</div>

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 “\>”

---

<div class="post-metadata">

**Author:** ![random52k](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/7bcc69/32.png) [@random52k](https://www.ruby-forum.com/u/random52k)\
**Post date:** [December 11, 2008, 11:02am UTC](https://www.ruby-forum.com/t/lambda-with-1-fails-as-gsub-block/155359/4 "2008-12-11T11:02:30Z")

</div>

On Thu, Dec 11, 2008 at 12:18 AM, Mike G. [removed\_email\_address@domain.invalid](mailto: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/](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
