简体   繁体   中英

Ruby on Rails - ActiveSupport: Array Extensions

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM