Silent out-of-index problems--how much of a problem are they

As a Python user starting to mess around with Ruby, one of my biggest
concerns is the fact that so many operations on lists ‘fail silently’
(return nil) when given list indices that are out of bounds. In
particular, I worry that this might produce hard-to-track down errors,
as the problem might not show up until one tries to do something with
the returned value(s); and by that may be somewhere far away in the
code. Certainly the guilty list access won’t show up in the call stack.

On the other hand, it’s often thought that dynamic languages will result
in lots of difficult-to-find problems due to the lack of strong typing,
but both Python and Ruby users know that’s not the case.

So my question is, in practice, how difficult is it to track down
index-out-of-bounds-errors in Ruby? It can certainly be a godawful
problem in C, and I’m pretty sure it would be in Python, too, if
exceptions weren’t thrown. And in Ruby, how does one track done where
such errors actually occur? In Python, I can simply look at the stack
trace.

This isn’t a criticism of Ruby. (Well, one aspect maybe). I’m looking at
Ruby because there are a lot of things (documentation tools,
consistency, gems, others) that it does better than Python. But I do
worry about silent index errors.

Thanks,
Ken

On 2006.10.13 13:34, Kenneth McDonald wrote:

but both Python and Ruby users know that’s not the case.
worry about silent index errors.
I can honestly say that I have never had this issue. I can see
that it might be worrying but it is just like any other language
feature–when you know it, you plan for it, you write your code
with it in mind.

And this is not to say it is a terrible inconvenience to have
to do this. The code seems to be more natural than with error
handling.

Oh–Arrays, not lists :slight_smile:

Kenneth McDonald wrote:

As a Python user starting to mess around with Ruby, one of my biggest
concerns is the fact that so many operations on lists ‘fail silently’

Is it failing, or simply returning a value that does not map to your
current expectations?


This isn’t a criticism of Ruby. (Well, one aspect maybe). I’m looking at
Ruby because there are a lot of things (documentation tools,
consistency, gems, others) that it does better than Python. But I do
worry about silent index errors.

Similar (rhetorical) question: What makes this an index error?

I think that the degree of difficulty people have in tracking down
undesired behavior is a factor of their beliefs about what the language
“should” do.

This is along the same lines of people having issues with zero being
True, or with zero-based indexing, or significant indentation.
There’s no objective reality for a programming language, no absolute
right or wrong for how it behaves. The best one can hope for is a
consistent internal universe.


James B.

“People want simple stories.”

Kenneth McDonald wrote:

So my question is, in practice, how difficult is it to track down
index-out-of-bounds-errors in Ruby? It can certainly be a godawful
problem in C, and I’m pretty sure it would be in Python, too, if
exceptions weren’t thrown. And in Ruby, how does one track done where
such errors actually occur? In Python, I can simply look at the stack trace.

I personally haven’t had trouble with this. I thought I’d point out
that you can make Ruby yell if you like. In a simple example (using
only one form of the [] access call):

irb(main):001:0> a = [0,1,2,3]
=> [0, 1, 2, 3]
irb(main):002:0> a[5]
=> nil
irb(main):003:0> class Array
irb(main):004:1> alias_method :_lookup, :[]
irb(main):005:1> def
irb(main):006:2> raise “OutOfBounds” unless idx>=0 && idx<size
irb(main):007:2> _lookup( idx )
irb(main):008:2> end
irb(main):009:1> end
=> nil
irb(main):010:0> a[5]
RuntimeError: OutOfBounds
from (irb):6:in `[]’
from (irb):10
from :0
irb(main):011:0> a[3]
=> 3

Kenneth McDonald wrote:

So my question is, in practice, how difficult is it to track down
index-out-of-bounds-errors in Ruby?

Truthfully, I’m not sure I’ve ever had one.

The only real error I ever get from Ruby is when I attempt
to call ‘foo’ on object nil. :wink:

It’s sort of an “edge case” thing. Like in Java, the
“pointerless” language, where the most common runtime
error is “null pointer exception.”

Of course, probably some percentage of those nils were
from out-of-bound array accesses.

Hal

Kenneth McDonald wrote:

So my question is, in practice, how difficult is it to track down
index-out-of-bounds-errors in Ruby? It can certainly be a godawful
problem in C, and I’m pretty sure it would be in Python, too, if
exceptions weren’t thrown. And in Ruby, how does one track done where
such errors actually occur? In Python, I can simply look at the stack
trace.

In general, ruby encourages you to use iterators more than indexing
(though of course not always), which avoids the issue.

In many cases, you are expecting that the array may have some nil
entries, so the bounds question isn’t really different from the question
of whether there was a real object at that index. You have to deal with
that case anyway (I presume even in python). Maybe you explicitly raise
an exception when [] returns nil:

elt = a[i] || (raise IndexError, “missing entry at #{i}”)

(of course, this will also raise an error on a false value, as well as
nil).

On Oct 12, 2006, at 11:34 PM, Kenneth McDonald wrote:

As a Python user starting to mess around with Ruby, one of my
biggest concerns is the fact that so many operations on lists ‘fail
silently’ (return nil) when given list indices that are out of bounds.

As has been shown, Array does include a fetch() method that throws
IndexError. I would say the fact that Ruby has an entire error type
just for this case shows that it is not being ignored.

In practice, this just isn’t much of an issue in Ruby. Like off-by-
one errors, this pretty much just goes away with the pervasive use of
iterators.

So my question is, in practice, how difficult is it to track down
index-out-of-bounds-errors in Ruby?

Well, Rubyists are big fans of Test Driven Development (TDD). Two of
the many advantages of TDD are that it causes you to write very small
methods and isolate the issues of those methods with tightly focused
tests. When doing this, it should be fairly rare that you are
scanning hundreds of line of code for a trivial out of bounds error
like this. That’s why we like it. :wink:

James Edward G. II

-----BEGIN PGP SIGNED MESSAGE-----

In article [email protected],
Kenneth McDonald [email protected] wrote:

So my question is, in practice, how difficult is it to track down
index-out-of-bounds-errors in Ruby? It can certainly be a godawful
problem in C, and I’m pretty sure it would be in Python, too, if
exceptions weren’t thrown. And in Ruby, how does one track done where
such errors actually occur? In Python, I can simply look at the stack trace.

If you use the Ruby error handling methodology, it’s generally
pretty simple since nil has few methods. Most times if you’re
accessing an Array element you’re going to do something with it,
so the error crops up fairly immediately. Unfortunately, it does
require this complicated setup %-).

begin

rescue => error
print error.inspect
end

that and some introspective code in method_missing will go a long
ways toward catching most runtime errors. I’m pretty sure you can
get a full stack trace if you need it, but I’ve never needed it.

_ Booker C. Bense

-----BEGIN PGP SIGNATURE-----
Version: 2.6.2

iQCVAwUBRS+kxGTWTAjn5N/lAQGe4gQAgLETOnvA3IukC0PYARa3lLZUacvOGGlE
uZ5vFv5xF+fho2cwm55i3sQlEJlRr8YmdgAdA3MfMLbFi/rELIMywSM6aJeQkq61
PkuqG+Swj8Xzq8pWEEbiTT6Q7zTnOyC0Qm84TZTOzNixX4ulQ2h2Dp87aIkkHV1M
mWhp6Fzg3Zg=
=YuKL
-----END PGP SIGNATURE-----