TIL Ruby is more forgiving when handling empty arrays that Python is with empty lists. If you try to access a non-existent index in Ruby you get a nil
back. In Python you get an IndexError
. I prefer the Python approach. It’s more straightforward.
Though Python also has a curious way that allows you to work around IndexError
by trying to access a range of items in the List. And Ruby does also have an approach that will give you an appropriate error if the index is out of bounds. So who knows what the logic behind all of this is supposed to be ….
Python Version
Compare the following Python commands
empty = [] arr = ["here","are","some","words"] empty[0] arr[0] empty[0:1] arr[0:1] " ".join(empty[0:1]) " ".join(arr[0:1])
Results of the Python commands:
>>> empty = [] >>> arr = ["here","are","some","words"] >>> empty[0] Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: list index out of range >>> arr[0] 'here' >>> empty[0:0] [] >>> arr[0:0] ['here'] >>> " ".join(empty[0:0]) '' >>> " ".join(arr[0:0]) 'here'
Ruby version
See the following Ruby commands
empty = [] arr = ["here","are","some","words"] empty[0] arr[0] empty[0..0] arr[0..0] empty[0..0].join(" ") arr[0..0].join(" ")
Results of the Ruby commands:
irb(main):007:0> empty = [] => [] irb(main):008:0> arr = ["here","are","some","words"] => ["here", "are", "some", "words"] irb(main):009:0> empty[0] => nil irb(main):010:0> arr[0] => "here" irb(main):011:0> empty[0..0] => [] irb(main):012:0> arr[0..0] => ["here"] irb(main):013:0> empty[0..0].join(" ") => "" irb(main):014:0> arr[0..0].join(" ") => "here"
Comparison
Python is pretty unforgiving if you try to access a non-existent element. Ruby is forgiving enough to give you a nil
if the element is non-existent. Downside of the Ruby approach is that you don’t know if the nil means “there was a nil there” or “there was nothing there”.
If you want the less forgiving approach in Ruby you can use fetch like so:
irb(main):031:0> empty => [] irb(main):032:0> empty.fetch(0) Traceback (most recent call last): 5: from /snap/ruby/132/bin/irb:23:in `<main>' 4: from /snap/ruby/132/bin/irb:23:in `load' 3: from /snap/ruby/132/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>' 2: from (irb):32 1: from (irb):32:in `fetch' IndexError (index 0 outside of array bounds: 0...0)