diff --git a/mrblib/range.rb b/mrblib/range.rb index fb217f771..f808053ca 100644 --- a/mrblib/range.rb +++ b/mrblib/range.rb @@ -79,8 +79,18 @@ class Range h end + ## + # call-seq: + # rng.to_a -> array + # rng.entries -> array + # + # Returns an array containing the items in the range. + # + # (1..7).to_a #=> [1, 2, 3, 4, 5, 6, 7] + # (1..).to_a #=> RangeError: cannot convert endless range to an array def to_a - raise RangeError, "cannot convert endless range to an array" if self.last.nil? + a = __num_to_a + return a if a super end alias entries to_a diff --git a/src/range.c b/src/range.c index 3ef4b14f5..1615f03b2 100644 --- a/src/range.c +++ b/src/range.c @@ -342,6 +342,55 @@ range_initialize_copy(mrb_state *mrb, mrb_value copy) return copy; } +static mrb_value +range_num_to_a(mrb_state *mrb, mrb_value range) +{ + struct RRange *r = mrb_range_ptr(mrb, range); + mrb_value beg = RANGE_BEG(r); + mrb_value end = RANGE_END(r); + mrb_value ary; + + if (mrb_nil_p(end)) { + mrb_raise(mrb, E_RANGE_ERROR, "cannot convert endless range to an array"); + } + if (mrb_integer_p(beg)) { + if (mrb_integer_p(end)) { + mrb_int a = mrb_integer(beg); + mrb_int b = mrb_integer(end); + mrb_int len = b - a; + + if (!RANGE_EXCL(r)) len++; + ary = mrb_ary_new_capa(mrb, len); + for (mrb_int i=0; i