summaryrefslogtreecommitdiff
path: root/array.c
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2023-03-10 01:33:00 +0900
committerKoichi Sasada <ko1@atdot.net>2023-03-23 14:03:12 +0900
commit0112a5b3423ddb2ddf46c4392f23f9b75128568e (patch)
tree388f54d8dbd34f3dfa96d02ffc37b421fa29e6a4 /array.c
parentc9fd81b860b5ec193ba57c73c740955937452497 (diff)
downloadruby-0112a5b3423ddb2ddf46c4392f23f9b75128568e.tar.gz
`Array#first` and `Array#last` in Ruby
Diffstat (limited to 'array.c')
-rw-r--r--array.c47
1 files changed, 30 insertions, 17 deletions
diff --git a/array.c b/array.c
index 83d1c9ced6..64bc744aac 100644
--- a/array.c
+++ b/array.c
@@ -1428,20 +1428,11 @@ enum ary_take_pos_flags
};
static VALUE
-ary_take_first_or_last(int argc, const VALUE *argv, VALUE ary, enum ary_take_pos_flags last)
+ary_take_first_or_last_n(VALUE ary, long n, enum ary_take_pos_flags last)
{
- long n;
- long len;
+ long len = RARRAY_LEN(ary);
long offset = 0;
- argc = rb_check_arity(argc, 0, 1);
- /* the case optional argument is omitted should be handled in
- * callers of this function. if another arity case is added,
- * this arity check needs to rewrite. */
- RUBY_ASSERT_ALWAYS(argc == 1);
-
- n = NUM2LONG(argv[0]);
- len = RARRAY_LEN(ary);
if (n > len) {
n = len;
}
@@ -1454,6 +1445,17 @@ ary_take_first_or_last(int argc, const VALUE *argv, VALUE ary, enum ary_take_pos
return ary_make_partial(ary, rb_cArray, offset, n);
}
+static VALUE
+ary_take_first_or_last(int argc, const VALUE *argv, VALUE ary, enum ary_take_pos_flags last)
+{
+ argc = rb_check_arity(argc, 0, 1);
+ /* the case optional argument is omitted should be handled in
+ * callers of this function. if another arity case is added,
+ * this arity check needs to rewrite. */
+ RUBY_ASSERT_ALWAYS(argc == 1);
+ return ary_take_first_or_last_n(ary, NUM2LONG(argv[0]), last);
+}
+
/*
* call-seq:
* array << object -> self
@@ -2027,6 +2029,7 @@ rb_ary_at(VALUE ary, VALUE pos)
return rb_ary_entry(ary, NUM2LONG(pos));
}
+#if 0
/*
* call-seq:
* array.first -> object or nil
@@ -2071,6 +2074,20 @@ rb_ary_first(int argc, VALUE *argv, VALUE ary)
return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST);
}
}
+#endif
+
+static VALUE
+ary_first(VALUE self)
+{
+ return (RARRAY_LEN(self) == 0) ? Qnil : RARRAY_AREF(self, 0);
+}
+
+static VALUE
+ary_last(VALUE self)
+{
+ long len = RARRAY_LEN(self);
+ return (len == 0) ? Qnil : RARRAY_AREF(self, len-1);
+}
/*
* call-seq:
@@ -2107,12 +2124,10 @@ rb_ary_first(int argc, VALUE *argv, VALUE ary)
*/
VALUE
-rb_ary_last(int argc, const VALUE *argv, VALUE ary)
+rb_ary_last(int argc, const VALUE *argv, VALUE ary) // used by parse.y
{
if (argc == 0) {
- long len = RARRAY_LEN(ary);
- if (len == 0) return Qnil;
- return RARRAY_AREF(ary, len-1);
+ return ary_last(ary);
}
else {
return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_LAST);
@@ -8809,8 +8824,6 @@ Init_Array(void)
rb_define_method(rb_cArray, "[]=", rb_ary_aset, -1);
rb_define_method(rb_cArray, "at", rb_ary_at, 1);
rb_define_method(rb_cArray, "fetch", rb_ary_fetch, -1);
- rb_define_method(rb_cArray, "first", rb_ary_first, -1);
- rb_define_method(rb_cArray, "last", rb_ary_last, -1);
rb_define_method(rb_cArray, "concat", rb_ary_concat_multi, -1);
rb_define_method(rb_cArray, "union", rb_ary_union_multi, -1);
rb_define_method(rb_cArray, "difference", rb_ary_difference_multi, -1);