Today’s Ruby Tuesday covers a variation of one of my personal favorite set of Ruby methods, Array#fetch.
Array.fetch
takes an integer for an argument and gets the element for a given index, using 0-based index scheme.
icao = [:alpha, :bravo, :charlie, :delta, :foxtrot] # => [:alpha, :bravo, :charlie, :delta, :foxtrot] icao.fetch 1 # => :bravo icao.fetch 0 # => :alpha
It also can get you the elements walking backward from a list
icao.fetch -1 # => :foxtrot icao.fetch -4 # => :bravo
If an index is out of bounds of the array, either positive of negative, an IndexError
is raised.
icao.fetch 5 # IndexError: index 5 outside of array bounds: -5...5 # from (pry):5:in `fetch' icao.fetch -7 # IndexError: index -7 outside of array bounds: -5...5 # from (pry):11:in `fetch'
At this point, I can hear you saying:
So what?! I can do this using a subscript to an array and not get exceptions but a nil when something is not found.
–You
icao[4] # => :foxtrot icao[0] # => :alpha icao[-1] # => :foxtrot icao[-7] # => nil icao[5] # => nil
And you would be right.
But where you might run into trouble with just using a subscript index, is if you have nil
s in your array.
some_nils[2] # => nil some_nils[100] # => nil
This is where Array#fetch
makes its way to one of my favorite Ruby methods.
When you decide to use Array#fetch
over just subscripts, you can specify a default value that you get back if the index is out of bounds.
icao.fetch 2, :fubar # => :charlie icao.fetch 5, :snafu # => :snafu icao.fetch -7, :fubar # => :fubar
And to top it off, you can even pass a whole block which is called with the index passed to fetch, so you can do more detailed logic if needed.
icao.fetch(-7) { |index| "SNAFU occured trying to fetch with index #{index}" } # => "SNAFU occured trying to fetch with index -7"
–Proctor