How to make objects that can set $1 when obj =~ /(.)/ is cal

Something like that would be a reasonable thing to do:

class Foo
def initialize(t)
@text = t
end
def =~(x)
@text =~ x
end
end

And it works for non-capturing regexps,
but when we want to capture something
$1 etc. are bound only within the =~ method,
and when the method returns they are
restored to their previous values.

Foo.new(“Hello”) =~ /(e)/ # => 1
$1 # => nil

Is it possible to somehow get =~ like that work,
even if it takes heavy metaprogramming hackery ?

Tomasz W. wrote:

even if it takes heavy metaprogramming hackery ?
The simplest solution might be to use #match:

class Foo
def initialize(t)
@text = t
end
def =~(x)
x.match @text
end
end

md = Foo.new(“Hello”) =~ /(e)l/
=> #MatchData:0x3a40c0

md.to_a
=> [“el”, “e”]

You can do more of course, like storing MatchData along with your Foo
instance etc. What problem are you trying to solve?

Kind regards

robert

On 8/8/06, Mauricio F. [email protected] wrote:

And it works for non-capturing regexps,

[ruby-talk:202600]

I finally got a working solution, using Binding.of_caller.
Not very elegant, but it works:

class Foo
def =~(pattern)
rv = (@text =~ pattern)
Binding.of_caller {|binding|
set_rx_vars = eval(“lambda{|md| $~ = md}”, binding)
set_rx_vars.call($~)
rv
}
end
end

On Tue, Aug 08, 2006 at 02:51:37PM +0900, Tomasz W. wrote:

but when we want to capture something
$1 etc. are bound only within the =~ method,
and when the method returns they are
restored to their previous values.

Foo.new(“Hello”) =~ /(e)/ # => 1
$1 # => nil

Is it possible to somehow get =~ like that work,
even if it takes heavy metaprogramming hackery ?

[ruby-talk:202600]