Feature #1882
closedMatchData#==
Added by runpaint (Run Paint Run Run) about 16 years ago. Updated over 14 years ago.
Description
=begin
Terribly unimportant, even by my standards, but could MatchData have a sensible #== defined? Currently two logically identical MatchData objects return false for #==.
a = 'haystack'.match(/hay/)
=> #<MatchData "hay">
b = 'haystack'.match(/hay/)
=> #<MatchData "hay">
a != b
=> true
=end
        
          
          Updated by nobu (Nobuyoshi Nakada) about 16 years ago
          
          
        
        
          
            Actions
          
          #1
        
      
      =begin
Hi,
At Wed, 5 Aug 2009 01:29:40 +0900,
Run Paint Run Run wrote in [ruby-core:24748]:
Terribly unimportant, even by my standards, but could
MatchData have a sensible #== defined? Currently two
logically identical MatchData objects return false for #==.
And #hash and #eql? too?
Index: re.c¶
--- re.c	(revision 24394)
+++ re.c	(working copy)
@@ -2531,4 +2531,53 @@ rb_reg_equal(VALUE re1, VALUE re2)
}
+/*
- 
- call-seq:
 
 - 
- mtch.hash => integer
 
 - 
 - 
- Produce a hash based on the target string, regexp and matched
 
 - 
- positions of this matchdata.
 
 - */
 
+static VALUE
+match_hash(VALUE match)
+{
- const struct re_registers *regs;
 - VALUE h;
 - unsigned long hashval = rb_hash_start(rb_str_hash(RMATCH(match)->str));
 - h = rb_reg_hash(RMATCH(match)->regexp);
 - rb_hash_uint(hashval, FIX2LONG(h));
 - regs = RMATCH_REGS(match);
 - hashval = rb_hash_uint(hashval, regs->num_regs);
 - hashval = rb_hash_uint(hashval, rb_memhash(regs->beg, regs->num_regs * sizeof(*regs->beg)));
 - hashval = rb_hash_uint(hashval, rb_memhash(regs->end, regs->num_regs * sizeof(*regs->end)));
 - hashval = rb_hash_end(hashval);
 - return LONG2FIX(hashval);
+} 
+/*
- 
- call-seq:
 
 - 
- mtch == mtch2 => true or false
 
 - 
 - 
- Equality---Two matchdata are equal if their target strings,
 
 - 
- patterns, and matched positions are identical.
 
 - */
 
+static VALUE
+match_equal(VALUE match1, VALUE match2)
+{
- const struct re_registers *regs1, *regs2;
 - if (match1 == match2) return Qtrue;
 - if (TYPE(match2) != T_MATCH) return Qfalse;
 - if (!rb_str_equal(RMATCH(match1)->str, RMATCH(match2)->str)) return Qfalse;
 - if (!rb_reg_equal(RMATCH(match1)->regexp, RMATCH(match2)->regexp)) return Qfalse;
 - regs1 = RMATCH_REGS(match1);
 - regs2 = RMATCH_REGS(match2);
 - if (regs1->num_regs != regs2->num_regs) return Qfalse;
 - if (memcmp(regs1->beg, regs2->beg, regs1->num_regs * sizeof(*regs1->beg))) return Qfalse;
 - if (memcmp(regs1->end, regs2->end, regs1->num_regs * sizeof(*regs1->end))) return Qfalse;
 - return Qtrue;
+} 
static VALUE
reg_operand(VALUE s, int check)
@@ -3451,3 +3500,6 @@ Init_Regexp(void)
rb_define_method(rb_cMatch, "inspect", match_inspect, 0);
rb_define_method(rb_cMatch, "string", match_string, 0);
- rb_define_method(rb_cMatch, "hash", match_hash, 0);
 - rb_define_method(rb_cMatch, "eql?", match_equal, 1);
 - rb_define_method(rb_cMatch, "==", match_equal, 1);
}
Index: test/ruby/test_regexp.rb
===================================================================
--- test/ruby/test_regexp.rb (revision 24394)
+++ test/ruby/test_regexp.rb (working copy)
@@ -765,3 +765,11 @@ class TestRegexp < Test::Unit::TestCase
assert_nothing_raised { 0x7fffffff.chr("utf-8").size }
end - def test_matchdata
 - a = "haystack".match(/hay/)
 - b = "haystack".match(/hay/)
 - assert_equal(a, b)
 - h = {a => 42}
 - assert_equal(42, h[b])
 - end
end
 
--
Nobu Nakada
=end
        
          
          Updated by runpaint (Run Paint Run Run) about 16 years ago
          
          
        
        
          
            Actions
          
          #2
        
      
      =begin
Your speed never ceases to amaze, nobu...
And #hash and #eql? too?
I didn't want to be greedy. ;-)
That looks great, thank you. :-)
=end
        
          
          Updated by nobu (Nobuyoshi Nakada) about 16 years ago
          
          
        
        
          
            Actions
          
          #3
        
      
      - Status changed from Open to Closed
 - % Done changed from 0 to 100
 
=begin
Applied in changeset r24753.
=end
        
          
          Updated by kstephens (Kurt  Stephens) about 16 years ago
          
          
        
        
          
            Actions
          
          #4
        
      
      =begin
- if (!rb_reg_equal(RMATCH(match1)->regexp, RMATCH(match2)->regexp)) return Qfalse;
 
Is this really what we want here? Do we really care if the source Regexp is the same?
m1 = /(foo?)(bar)/.match("fobar")
m2 = /(fo)(bar)/.match("fobar")
m1[0] == m2[0]
m1[1] == m2[1]
m1[2] == m2[2]
=end