Weirich, James
11/19/2003 3:49:00 PM
From: matz@ruby-lang.org [mailto:matz@ruby-lang.org]
> If you update $~ (the match result), $&, $1, etc. would follow
> accordingly. So that the better RCR should be to create MatchData
> without built-in regular expression match, I think.
Wow, this solves a problem I was dealing with. I wanted to implement "sub"
on a array-like object such that list.sub(...) would be the same a calling
sub on each element of the list. The problem was that list.sub(/re/) { $1 }
would always give nil for the value of $1.
Here's my solution.
# -----------------------------------------------
class FileList < Array
class << self
attr_accessor :match_data
def set_match_data(md, block)
FileList.match_data = md
eval "$~ = FileList.match_data", block
end
end
def sub(re, &block)
collect do |item|
item.sub(re) {
FileList.set_match_data($~, block)
block.call
}
end
end
end
f = FileList.new
f << "a.c" << "b.c"
p f.sub(/^(.*)\.c$/) { "#{$1}.o" }
# ---------------------------------------------
The above solution is not thread safe, but that can be easily solved by
using a mutex in set_match_data. Comments welcome.
--
-- Jim Weirich / Compuware
-- FWP Capture Services
-- Phone: 859-386-8855