On 01/08/05, Garance A Drosehn <drosihn / gmail.com> wrote: > On 8/1/05, Garance A Drosehn <drosihn / gmail.com> wrote: > > > > The downside to this is that the regular-expression is now > > defined somewhere "far away" from the when-clause that > > uses it. After some testing I may need to make changes to > > the regexp, such as: > > > > re_simple = Regexp.new('(check|test) (\d+)') > > > > The thing is, by changing 'check' to '(check|test)', I have to > > remember that the when clause also needs to change from > > referencing $1 to referencing $2. [...] > > > > I was kinda wondering if it would make sense for ruby to > > support something like: > > > > re_simple = Regexp.new('check (\d+)') { cnum = $1 } > > > > so I could then have the when clause say: > > > > when re_simple > > check_number = cnum > > > > I realize this is a trivial example, but as the expressions get > > more involved, and the case-statement has many when's, it > > would be nice if I could have the compiled regular-expression > > set values on variable names that *I* pick, in addition to the > > standard values in a MatchData object. > > I thought about this some more after going home and getting > some sleep... One obvious question is what would be the > scope of the commands inside the { ...code-fragment...}. It > also occurred to me that I sometimes I make a match, and > then I pass around the resulting MatchData object to other > methods, and *they* do things based on info in MatchData. > > So, I came up with this idea: > > Allow MatchData to include some user-settable value, > which would initially be set to 'nil' at the time of the match. > And then support: > > re_simple = Regexp.new('check (\d+)') { |mdata| > mdata.userdata = mdata[1] > } > > or: > > re_simple = Regexp.new('check (\d+)') { |mdata| > mdata.userdata = Hash.new > mdata.userdata["cnum"] = mdata[1] > mdata.userdata["otherval"] = mdata[7] > } > > That way, all the variables that the user is setting will > be tied to the appropriate MatchData object. > > I almost think I could implement this by creating my own > subclasses for Regexp and MatchData... > You could define it like this: bschroed@black:~/svn/projekte/ruby-things$ cat regexp_data.rb class DataRegexp < Regexp def initialize(regexp, &block) @block = block @userdata = {} super(regexp) end def match(str) result = super(str) class <<result def userdata @userdata ||= {} end end @block[result] if @block result end end re_simple = DataRegexp.new('check (\d+)') { | mdata | mdata.userdata[:check_number] = mdata[1].to_i if mdata } if match = re_simple.match("Something") puts "Something matched" end if match = re_simple.match("check 12") puts "Checking #{match.userdata[:check_number]}" end bschroed@black:~/svn/projekte/ruby-things$ ruby regexp_data.rb Checking 12 regards, Brian -- http://ruby.brian-schroeder.de/ Stringed instrument chords: http://chordlist.brian-schroeder.de/