🚨
some Ruby tips
on programminglast updated 6/12/21
Like most stuff on the internet, this is really just a list.
Recently I've spent the bulk of my time writing Ruby and thanks to my teammates, have gotten exposed to some nice techniques I had not seen before. Below are a few of the simplest ones.
percent strings
Especially with long arrays of strings,  %w is handy because it saves us from copious punctuation. There's more on other types of percent strings here.
groceries = %w[eggs yogurt chicken]
# or... groceries = %w(eggs yogurt chicken)
groceries #=> ['eggs', 'yogurt', 'chicken']
# use %i for an array of symbols
groceries = %i[eggs yogurt chicken]
groceries #=> [:eggs, :yogurt, :chicken]
        pretend flag
Running rails g --help or rails g -h outputs a detailed help message, including this flag:
-p, [--pretend], [--no-pretend] # Run but do not make any changes
        We can append -p to any rails generate command to simulate what it does. 10/10 would recommend this before running rails destroy anything.
handling nil
I had typically used conditional statements to avoid calling methods on nil objects:
# blows up given a place that's nil
def get_city(place)
  place.address.city
end
get_city(a_real_place) #=> Realtown, USA
get_city(a_fake_place) #=> NoMethodError...
# this works
def get_city(place)
  place.address ? place.address.city : nil
end
get_city(a_real_place) #=> Realtown, USA
get_city(a_fake_place) #=> nil
        But #try and the safe navigation operator &. are often simpler:
def get_city(place)
  place.address.try(:city)
end
get_city(a_real_place) #=> Realtown, USA
get_city(a_fake_place) #=> nil
def get_city(place)
  place.address&.city
end
get_city(a_real_place) #=> Realtown, USA
get_city(a_fake_place) #=> nil
        #try can be difficult to debug because it will always return nil. A benefit of &., also known as the lonely operator, is that it will throw an error if the receiver doesn't respond to the method we're calling on it.
# if we spell 'city' incorrectly
def get_city(place)
  place.address.try(:citey)
end
get_city(a_fake_place) #=> nil
def get_city(place)
  place.address&.citey
end
get_city(a_fake_place) #=> NoMethodError...
        #dig is also great because it works for hashes and arrays:
person = {
  name: 'Ethan',
  address_attributes: {
    city: 'Los Angeles',
    state: 'California'
  }
}
person.dig(:address_attributes, :city) #=> Los Angeles
person.dig(:address_attributes, :zip) #=> nil
states = [
  ['AL', 'AK', 'AZ'],
  ['AR', 'CA', 'CO']
]
state.dig(1, 1) #=> 'CA'
state.dig(1, 5) #=> nil