In the extensions to the array class (rails/activesupport/lib/active_support/core_ext/array/access.rb) the following function is defined:
# Returns the beginning of the array up to +position+.
def to(position)
if position >= 0
take position + 1
else
self[0..position]
end
end
Why is it defined like this? Why can't we just do:
def to(position)
self[0..position]
end
According to the commit message of the change in the Rails code , it looks like they were trying to "Avoid creating range objects".
When I do arr[0..3]
, the 0..3
part becomes a Range
object, which then gets used to calculate the subarray. I'm guessing they were trying to save memory by avoiding this.
It's about efficiency. Since most use case (positive parameter) will fall into the if
branch and the Array#take
method easily gives the return, see implementation:
static VALUE
rb_ary_take(VALUE obj, VALUE n)
{
long len = NUM2LONG(n);
if (len < 0) {
# does not take negative parameter
rb_raise(rb_eArgError, "attempt to take negative size");
}
return rb_ary_subseq(obj, 0, len);
}
For the else
branch, we have to create a rang object since Array#take
does not take a negative parameter (see above c implementation) and hence a little more memory is used.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.