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

  • Thread starter Tomasz Wegrzanowski
  • Start date
T

Tomasz Wegrzanowski

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 ?
 
R

Robert Klemme

Tomasz said:
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 ?

The simplest solution might be to use #match:

class Foo
def initialize(t)
@text = t
end
def =~(x)
x.match @text
end
end
=> ["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
 
M

Mauricio Fernandez

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 ?

[ruby-talk:202600]
 
T

Tomasz Wegrzanowski

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 ?

[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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,209
Messages
2,571,088
Members
47,687
Latest member
IngridXxj

Latest Threads

Top