start_with
in place of regex RB-PR1021If a regex only checks if the string starts with a particular string, String#start_with?
can be used as a simpler and more efficient method.
Array.new()
with a block instead of .times
RB-PR1023Unary plus operator is faster than String#dup
. Note: String.new
(without operator) is not exactly the same as +''
. These differ in encoding. String.new.encoding
is always ASCII-8BIT. However, (+'').encoding
is the same as script encoding(e.g. UTF-8). So, if you expect ASCII-8BIT encoding, disable this issue, either in .rubocop.yml
, or in the occurrence it was raised, using skipcq
.
gsub(/\Aprefix/, '')
can be replaced by delete_prefix('prefix')
RB-PR1026The delete_prefix('prefix')
method is faster than gsub(/\Aprefix/, '')
.
gsub(/suffix\z/, '')
can be replaced by delete_suffix('suffix')
RB-PR1027The delete_suffix('suffix')
method is faster than gsub(/suffix\z/, '')
.
String#end_with?
instead of a regex match anchored to the end of the string RB-PR1009Instead of searching for a string pattern at the end of a string using regex, it is more efficient to simply use end_with?
instead.
Sizes of objects that we know to be static should not be computed. For example, we know the size of array in the snippet below to be 3
. We can directly use the value instead of calculating it first.
flat_map
to flatten maps RB-PR1011flat_map
is more efficient than flatten
. Refer here.
=~
in places where the MatchData
returned by #match
will not be used RB-PR1016The return value of =~
is an integral index/nil
and is more performant.
size
instead of count
RB-PR1020size
should be preferred over count
. Read more here.
tr
/delete
instead of gsub
RB-PR1022tr
/delete
are more efficient than gsub
.
Range#cover?
instead of Range#include?
RB-PR1014Range#include?
iterates over each item in a Range
to see if a specified item is there. In contrast, Range#cover?
simply compares the target item with the beginning and end points of the Range
. In a great majority of cases, this is what is wanted. For example:
yield
instead of block call RB-PR1015Use of a &block
parameter and block.call
can be replaced by yield
in some cases.
match?
over match
RB-PR1018String#match?
, Regexp#match?
, and Symbol#match?
are faster than match
, because the methods avoid creating a MatchData
object or saving backref. So, when MatchData
is not used, match?
can be used instead of match
.
reverse_each
instead of reverse.each
RB-PR1019reverse_each
is more efficient than reverse.each
. Read more here.
case
..when
can be modified for performance RB-PR1002Reordering when
conditions with a splat to the end of the when
branches can improve performance. Ruby has to allocate memory for the splat expansion every time that the case
-when
statement is run. Since Ruby does not support fall through inside of case
-when
, like some other languages do, the order of the when
branches should not matter. By placing any splat expansions at the end of the list of when
branches we will reduce the number of times that memory has to be allocated for the expansion. The exception to this is if multiple when
conditions can be true for any given condition. A likely scenario for this is defining a higher level when
condition to override a condition that is inside of the splat expansion.
casecmp
RB-PR1003Case-insensitive string comparison can be done more efficiently using casecmp
.
Methods compact
, flatten
and map
generate a new intermediate array that is discarded. It is faster to mutate the array when we know it's safe.
sort
, max
and min
with respective _by
methods RB-PR1005sort { |a, b| a.foo <=> b.foo }
can be replaced by sort_by(&:foo)
. This is true for max
and min
methods, too. All the sort
, min
and max
methods with block in the following example can be replaced by the respective _by
methods.
count
instead of select
/reject
RB-PR1006Usages of count
on an Enumerable
that follow calls to select
or reject
can be made more efficient. Querying logic can instead be passed to the count
call.