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.
2 Answers 2
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
-
\$\begingroup\$ named keywords are really nice, i had no idea about them. thanks! \$\endgroup\$dax– dax2015年04月13日 17:48:22 +00:00Commented Apr 13, 2015 at 17:48
-
\$\begingroup\$ That's some pretty code; nice and elegant. +1 \$\endgroup\$Evan Bechtol– Evan Bechtol2015年04月13日 17:57:23 +00:00Commented Apr 13, 2015 at 17:57
-
\$\begingroup\$ You could also write the first line,
@result.shift(offset) if offset
. \$\endgroup\$Cary Swoveland– Cary Swoveland2015年04月14日 02:30:20 +00:00Commented Apr 14, 2015 at 2:30
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.
-
\$\begingroup\$ Very nice, but where's your usual thorough explanation? Why does this work for various case? For example, what if
offset >= @result.size
or0 <= offset < @result.size
andoffset + limit >= @result.size
? \$\endgroup\$Cary Swoveland– Cary Swoveland2015年04月14日 02:46:02 +00:00Commented Apr 14, 2015 at 2:46 -
\$\begingroup\$ @CarySwoveland Indeed, the original version was all wrong. \$\endgroup\$200_success– 200_success2015年04月14日 03:10:49 +00:00Commented Apr 14, 2015 at 3:10