From 0112a5b3423ddb2ddf46c4392f23f9b75128568e Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Fri, 10 Mar 2023 01:33:00 +0900 Subject: `Array#first` and `Array#last` in Ruby --- array.c | 47 ++++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 17 deletions(-) (limited to 'array.c') 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); -- cgit v1.2.1