diff options
| -rw-r--r-- | mrblib/array.rb | 76 | ||||
| -rw-r--r-- | src/array.c | 64 |
2 files changed, 81 insertions, 59 deletions
diff --git a/mrblib/array.rb b/mrblib/array.rb index 718553e83..fedf4f33c 100644 --- a/mrblib/array.rb +++ b/mrblib/array.rb @@ -96,6 +96,82 @@ class Array alias to_s inspect ## + # Equality---Two arrays are equal if they contain the same number + # of elements and if each element is equal to (according to + # Object.==) the corresponding element in the other array. + # + # ISO 15.2.12.5.33 (x) + def ==(other) + other = self.__ary_eq(other) + return false if other == false + return true if other == true + len = self.size + i = 0 + while i < len + return false if self[i] != other[i] + i += 1 + end + return true + end + + ## + # Returns <code>true</code> if +self+ and _other_ are the same object, + # or are both arrays with the same content. + # + # ISO 15.2.12.5.34 (x) + def eql?(other) + other = self.__ary_eq(other) + return false if other == false + return true if other == true + len = self.size + i = 0 + while i < len + return false unless self[i].eql?(other[i]) + i += 1 + end + return true + end + + ## + # Comparison---Returns an integer (-1, 0, or +1) + # if this array is less than, equal to, or greater than <i>other_ary</i>. + # Each object in each array is compared (using <=>). If any value isn't + # equal, then that inequality is the return value. If all the + # values found are equal, then the return is based on a + # comparison of the array lengths. Thus, two arrays are + # ``equal'' according to <code>Array#<=></code> if and only if they have + # the same length and the value of each element is equal to the + # value of the corresponding element in the other array. + # + # ISO 15.2.12.5.36 (x) + def <=>(other) + len = self.size + begin + n = other.size + rescue NoMethodError + return nil + end + if len > n + len = n + end + i = 0 + while i < len + n = (self[i] <=> other[i]) + return n if n == nil + return n if n != 0 + i += 1 + end + len = self.size - other.size + if len == 0 + 0 + elsif len > 0 + 1 + else + -1 + end + end + + ## # Delete element with index +key+ def delete(key, &block) while i = self.index(key) diff --git a/src/array.c b/src/array.c index 42e36feb3..f225622e8 100644 --- a/src/array.c +++ b/src/array.c @@ -311,7 +311,7 @@ mrb_ary_plus(mrb_state *mrb, mrb_value self) * [ 1, 2, 3, 4, 5, 6 ] <=> [ 1, 2 ] #=> +1 * */ -static mrb_value +mrb_value mrb_ary_cmp(mrb_state *mrb, mrb_value ary1) { mrb_value ary2; @@ -1065,72 +1065,20 @@ mrb_ary_join_m(mrb_state *mrb, mrb_value ary) return mrb_ary_join(mrb, ary, sep); } -/* 15.2.12.5.33 (x) */ -/* - * call-seq: - * ary == other_ary -> bool - * - * Equality---Two arrays are equal if they contain the same number - * of elements and if each element is equal to (according to - * Object.==) the corresponding element in the other array. - * - * [ "a", "c" ] == [ "a", "c", 7 ] #=> false - * [ "a", "c", 7 ] == [ "a", "c", 7 ] #=> true - * [ "a", "c", 7 ] == [ "a", "d", "f" ] #=> false - * - */ - static mrb_value -mrb_ary_equal(mrb_state *mrb, mrb_value ary1) +mrb_ary_eq(mrb_state *mrb, mrb_value ary1) { mrb_value ary2; - mrb_int i; mrb_get_args(mrb, "o", &ary2); if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value(); if (mrb_special_const_p(ary2)) return mrb_false_value(); if (!mrb_array_p(ary2)) { - if (!mrb_respond_to(mrb, ary2, mrb_intern_lit(mrb, "to_ary"))) { - return mrb_false_value(); - } - else { - return mrb_bool_value(mrb_equal(mrb, ary2, ary1)); - } + return mrb_false_value(); } if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value(); - for (i=0; i<RARRAY_LEN(ary1); i++) { - if (!mrb_equal(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) { - return mrb_false_value(); - } - } - return mrb_true_value(); -} -/* 15.2.12.5.34 (x) */ -/* - * call-seq: - * ary.eql?(other) -> true or false - * - * Returns <code>true</code> if +self+ and _other_ are the same object, - * or are both arrays with the same content. - */ - -static mrb_value -mrb_ary_eql(mrb_state *mrb, mrb_value ary1) -{ - mrb_value ary2; - mrb_int i; - - mrb_get_args(mrb, "o", &ary2); - if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value(); - if (!mrb_array_p(ary2)) return mrb_false_value(); - if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return mrb_false_value(); - for (i=0; i<RARRAY_LEN(ary1); i++) { - if (!mrb_eql(mrb, ary_elt(ary1, i), ary_elt(ary2, i))) { - return mrb_false_value(); - } - } - return mrb_true_value(); + return ary2; } void @@ -1169,7 +1117,5 @@ mrb_init_array(mrb_state *mrb) mrb_define_method(mrb, a, "slice", mrb_ary_aget, MRB_ARGS_ANY()); /* 15.2.12.5.29 */ mrb_define_method(mrb, a, "unshift", mrb_ary_unshift_m, MRB_ARGS_ANY()); /* 15.2.12.5.30 */ - mrb_define_method(mrb, a, "==", mrb_ary_equal, MRB_ARGS_REQ(1)); /* 15.2.12.5.33 (x) */ - mrb_define_method(mrb, a, "eql?", mrb_ary_eql, MRB_ARGS_REQ(1)); /* 15.2.12.5.34 (x) */ - mrb_define_method(mrb, a, "<=>", mrb_ary_cmp, MRB_ARGS_REQ(1)); /* 15.2.12.5.36 (x) */ + mrb_define_method(mrb, a, "__ary_eq", mrb_ary_eq, MRB_ARGS_REQ(1)); } |
