Problem of discrete membership at Range#=== is that it returns unexpected 
result when treating float-like Classes. Class Time is represented as
float so
(Time.new...Time.new+5)===Time.new returns false. 
Time#to_int should be added | add check if object can to_f
Or apply my patch which idea is that object should care if he is at given range
I choose Comparable#between? but I rather change its arguments to low.between?(value, high,excl) because now value doesnt know what range represents and can only guess that they are same type.(I dont know how frequently its used. ) 
Written String#between? with has linear time to size of strings .

BTW Now I know that I am addicted to ruby because I tried three times post it to
ruby-core / ruby-lang.rb 

Index: range.c
===================================================================
RCS file: /src/ruby/range.c,v
retrieving revision 1.84
diff -u -p -r1.84 range.c
--- range.c	3 Aug 2006 06:21:03 -0000	1.84
+++ range.c	11 Aug 2006 16:54:46 -0000
@@ -14,7 +14,7 @@
 #include "env.h"
 
 VALUE rb_cRange;
-static ID id_cmp, id_succ, id_beg, id_end, id_excl;
+static ID id_cmp, id_succ, id_beg, id_end, id_excl,id_between;
 
 #define EXCL(r) RTEST(rb_ivar_get((r), id_excl))
 #define SET_EXCL(r,v) rb_ivar_set((r), id_excl, (v) ? Qtrue : Qfalse)
@@ -139,6 +139,15 @@ r_lt(VALUE a, VALUE b)
     if (rb_cmpint(r, a, b) < 0) return Qtrue;
     return Qfalse;
 }
+static int
+r_eq(VALUE a, VALUE b)
+{
+    VALUE r = rb_funcall(a, id_cmp, 1, b);
+
+    if (NIL_P(r)) return Qfalse;
+    if (rb_cmpint(r, a, b) == 0) return Qtrue;
+    return Qfalse;
+}
 
 static int
 r_le(VALUE a, VALUE b)
@@ -621,23 +630,10 @@ range_include(VALUE range, VALUE val)
 {
     VALUE beg = rb_ivar_get(range, id_beg);
     VALUE end = rb_ivar_get(range, id_end);
-    int nv = FIXNUM_P(beg) || FIXNUM_P(end) ||
-	     rb_obj_is_kind_of(beg, rb_cNumeric) ||
-	     rb_obj_is_kind_of(end, rb_cNumeric);
-
-    if (nv ||
-	!NIL_P(rb_check_to_integer(beg, "to_int")) ||
-	!NIL_P(rb_check_to_integer(end, "to_int"))) {
-	if (r_le(beg, val)) {
-	    if (EXCL(range)) {
-		if (r_lt(val, end)) return Qtrue;
-	    }
-	    else {
-		if (r_le(val, end)) return Qtrue;
-	    }
-	}
-	return Qfalse;
-    }
+		if (rb_respond_to(val,id_between)){
+			if (EXCL(range) && r_eq(val, end)) return Qfalse;
+			return rb_funcall(val,id_between,2,beg,end);
+		}
     ruby_frame->this_func = rb_intern("include?");
     return rb_call_super(1, &val);
 }
@@ -758,4 +754,6 @@ Init_Range(void)
     id_beg = rb_intern("begin");
     id_end = rb_intern("end");
     id_excl = rb_intern("excl");
+    id_between = rb_intern("between?");
+
 }
Index: string.c
===================================================================
RCS file: /src/ruby/string.c,v
retrieving revision 1.255
diff -u -p -r1.255 string.c
--- string.c	26 Jul 2006 07:43:16 -0000	1.255
+++ string.c	11 Aug 2006 16:56:15 -0000
@@ -997,6 +997,34 @@ rb_str_cmp_m(VALUE str1, VALUE str2)
     return LONG2NUM(result);
 }
 
+static inline int str_same(const char a,const char b){
+	if (a==b||b<'0') 
+		return 1;
+	if ('0'<= a && a<='9') return ('0'<=b && b<='9'); 
+	if ('a'<= a && a<='z') return ('a'<=b && b<='z'); 
+	if ('A'<= a && a<='Z') return ('A'<=b && b<='Z'); 
+	return 0;
+}
+static VALUE rb_str_between(VALUE self,VALUE low,VALUE hig){
+       str=rb_funcall(self,rb_intern("to_str"),0);//dont know what will inherance do with it
+	low=rb_funcall(low,rb_intern("to_str"),0); 
+	hig=rb_funcall(hig,rb_intern("to_str"),0); 	
+	char *s=RSTRING(str)->ptr,*l=RSTRING(low)->ptr,*h=RSTRING(hig)->ptr;
+	int ss=RSTRING(str)->len,sl=RSTRING(low)->len,sh=RSTRING(hig)->len;
+	if ( ss<sl && ss>sh) return Qfalse;
+	int i;
+	for (i=0;i<sl;i++)
+		if (!str_same(l[i],s[i])) return Qfalse;
+	for (i=sl;i<ss;i++)
+		if (!str_same(l[ss-1],s[i])) return Qfalse;
+	if (sl==ss){
+		if (strcmp(l,s)>0)return Qfalse;
+	}
+	if (ss==sh){
+		if (strcmp(s,h)>=0)return Qfalse;
+	}
+	return Qtrue;
+}
+
 /*
  *  call-seq:
  *     str.casecmp(other_str)   => -1, 0, +1
@@ -4293,6 +4321,7 @@ Init_String(void)
     rb_define_method(rb_cString, "initialize_copy", rb_str_replace, 1);
     rb_define_method(rb_cString, "<=>", rb_str_cmp_m, 1);
     rb_define_method(rb_cString, "==", rb_str_equal, 1);
+    rb_define_method(rb_cString, "between?", rb_str_between, 2);
     rb_define_method(rb_cString, "eql?", rb_str_eql, 1);
     rb_define_method(rb_cString, "hash", rb_str_hash_m, 0);
     rb_define_method(rb_cString, "casecmp", rb_str_casecmp, 1);