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

K

Kenneth McDonald

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
 
J

James Britt

Kenneth said:
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.
 
E

Eero Saynatkari

--++alDQ2ROsODg1x+
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

As a Python user starting to mess around with Ruby, one of my biggest=20
concerns is the fact that so many operations on lists 'fail silently'=20
(return nil) when given list indices that are out of bounds. In=20
particular, I worry that this might produce hard-to-track down errors,=20
as the problem might not show up until one tries to do something with=20
the returned value(s); and by that may be somewhere far away in the=20
code. Certainly the guilty list access won't show up in the call stack.
=20
On the other hand, it's often thought that dynamic languages will result= =20
in lots of difficult-to-find problems due to the lack of strong typing,= =20
but both Python and Ruby users know that's not the case.
=20
So my question is, _in practice_, how difficult is it to track down=20
index-out-of-bounds-errors in Ruby? It can certainly be a godawful=20
problem in C, and I'm pretty sure it would be in Python, too, if=20
exceptions weren't thrown. And in Ruby, how does one track done where=20
such errors actually occur? In Python, I can simply look at the stack tra= ce.
=20
This isn't a criticism of Ruby. (Well, one aspect maybe). I'm looking at= =20
Ruby because there are a lot of things (documentation tools,=20
consistency, gems, others) that it does better than Python. But I do=20
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 :)

--++alDQ2ROsODg1x+
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (FreeBSD)

iD8DBQFFLx1t7Nh7RM4TrhIRAjuGAKCs7ndZ5yk8nnKEvslg0RfMy1XMlwCgqx5s
ci/Twds1F5nX4sO/Qcp3nNQ=
=EJWX
-----END PGP SIGNATURE-----

--++alDQ2ROsODg1x+--
 
P

Phrogz

Kenneth said:
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 []( idx )
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
 
J

Joel VanderWerf

Kenneth said:
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 || (raise IndexError, "missing entry at #{i}")

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

Hal Fulton

Kenneth said:
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. ;)

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
 
J

James Edward Gray II

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. ;)

James Edward Gray II
 
B

Booker C. Bense

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

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
<code>
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-----
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,215
Messages
2,571,113
Members
47,708
Latest member
SharonMaes

Latest Threads

Top