I'm not really into patterns, but here are a few pieces of code that show up a lot but can be written another (arguably) better way.
Rescuing an Exception in a Method
How
not to do it:
def some_method
begin
do_something
rescue Exception => ex
handle_exception(ex)
end
end
The 'begin' is unnecessary. The method can be implemented as:
def some_method
do_something
rescue Exception => ex
handle_exception(ex)
end
Rescuing Any Exception
I doubled up on the last example. If you want to rescue any Exception, rather than:
rescue Exception => ex
write:
rescue => ex
Update: I was wrong about this. Rescue without a class will only rescue up to StandardError, not Exception.
Selecting Some Elements out of a Collection
How not to write it:
odd_numbers = []
[1,2,3,4,5,6,7,8].each do |number|
odd_numbers << number if number % 2 == 1
end
This should be implemented using Enumerable#select. Enumerable is a good module to be familiar with. The better implementation:
odd_numbers = [1,2,3,4,5,6,7,8].select { |number| number % 2 == 1 }
odd_numbers = [1,2,3,4,5,6,7,8].select(&:odd?)
Variable Assignment from If (or Case) Statement
Again, somebody may argue readability on this one, but I like it better. Rather than:
if something_is_true?
my_variable = :some_value
else
my_variable = :another_value
end
An if statement will return a value, so write the above section of code as:
my_variable = if something_is_true?
:some_value
else
:another_value
end
Returning from an Iterator
Alright, one more Enumerable example. Most of the time if you write a piece of code that returns from an iterator, such as an .each loop, you're looking for a specific element in the collection. Rather than:
def my_method
collection.each do |item|
return item if item.right_one?
end
:item_not_found
end
You can write:
def my_method
collection.detect { |item| item.right_one? } || :item_not_found
end
The detect method lives in the Enumerable module. It will return the first item in the collection which when passed to the block evaluates to true. If no items are found, .detect returns nil. This allows us to use || to return a default value if we need to.