2
\$\begingroup\$

I'm refactoring an old gateway and came across the following method:

def apply_limit_and_offset(options)
 limit = options[:limit]
 offset = options[:offset]
 @result = if offset
 @result.drop offset
 else
 @result
 end
 @result = if limit
 @result.first limit
 else
 @result
 end
 @result
end

@result is an Array of objects.

Any suggestions on how to refactor this? It works just fine, but multiple if statements make me feel gross.

200_success
145k22 gold badges190 silver badges478 bronze badges
asked Apr 13, 2015 at 15:17
\$\endgroup\$
0

2 Answers 2

8
\$\begingroup\$

Some notes:

  • Be consistent with the use of parens.

  • Use ternary expressions (?) to reduce short conditionals.

  • If you are using Ruby>= 2.0, check named keywords.

  • The resulting expression of an assignment is its value, so you can remove the last @result

  • What looks gross to me are those in-place updates of @result, but this goes beyond the scope of the question.

With Ruby>= 2.0, I'd write:

def apply_limit_and_offset(limit: nil, offset: nil)
 @result = offset ? @result.drop(offset) : @result
 @result = limit ? @result.first(limit) : @result
end
answered Apr 13, 2015 at 16:19
\$\endgroup\$
3
  • \$\begingroup\$ named keywords are really nice, i had no idea about them. thanks! \$\endgroup\$ Commented Apr 13, 2015 at 17:48
  • \$\begingroup\$ That's some pretty code; nice and elegant. +1 \$\endgroup\$ Commented Apr 13, 2015 at 17:57
  • \$\begingroup\$ You could also write the first line, @result.shift(offset) if offset. \$\endgroup\$ Commented Apr 14, 2015 at 2:30
4
\$\begingroup\$

Your operation is basically equivalent to Array#slice, so that is how I would write it.

def apply_limit_and_offset(options)
 @result = @result.slice(options[:offset] || 0,
 options[:limit] || @result.length) || []
end

#slice appears to tolerate an options[:limit] that goes beyond the end of the array. However, if options[:offset] is out of range, then #slice returns nil, so we need to add || [] at the end to make it an empty array.

answered Apr 13, 2015 at 17:59
\$\endgroup\$
2
  • \$\begingroup\$ Very nice, but where's your usual thorough explanation? Why does this work for various case? For example, what if offset >= @result.size or 0 <= offset < @result.size and offset + limit >= @result.size? \$\endgroup\$ Commented Apr 14, 2015 at 2:46
  • \$\begingroup\$ @CarySwoveland Indeed, the original version was all wrong. \$\endgroup\$ Commented Apr 14, 2015 at 3:10

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.