summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--mrblib/array.rb76
-rw-r--r--src/array.c64
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));
}