Any way to get lists to throw exceptions on incorrect accesses?

K

Kenneth McDonald

I'm slowly doing more in Ruby (in addition to what I do in Python), as I
like the cleanliness of the language. However, one thing that I really
_don't_ like is the fact that an attempt to access a non-existent list
item silently returns nil, rather than throwing an exception. Is there a
way to make this more strict? Hashes have the same behavior, but since
they can be assigned a default block, that isn't nearly so much of a
problem.

I know I could change List behavior, but there are very obvious reasons
why that's a Bad Thing. I could also subclass list, but then I miss all
of the syntactic niceties of lists. And both solutions impose an extra
level of calling for what will be very frequent actions.

Any thoughts welcome,
Ken
 
J

Jamey Cribbs

Kenneth said:
I'm slowly doing more in Ruby (in addition to what I do in Python), as
I like the cleanliness of the language. However, one thing that I
really _don't_ like is the fact that an attempt to access a
non-existent list item silently returns nil, rather than throwing an
exception. Is there a way to make this more strict? Hashes have the
same behavior, but since they can be assigned a default block, that
isn't nearly so much of a problem.

I know I could change List behavior, but there are very obvious
reasons why that's a Bad Thing. I could also subclass list, but then I
miss all of the syntactic niceties of lists. And both solutions impose
an extra level of calling for what will be very frequent actions.

Array#fetch will raise an exception if the index does not exist.

Jamey
 
K

Kenneth McDonald

Thanks. Too bad I can't use the [] indexing notation, though.

I'm starting to learn the Ruby libraries...

Ken
 
K

_Kevin

Thanks. Too bad I can't use the [] indexing notation, though.

I'm starting to learn the Ruby libraries...

Ken

Array#fetch will raise an exception if the index does not exist.

Set the default proc to raise an exception...

a=Hash.new {raise ArgumentError}
a[1] #=> raises an ArgumentError

_Kevin
 
E

Eero Saynatkari

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

I'm slowly doing more in Ruby (in addition to what I do in Python), as I= =20
like the cleanliness of the language. However, one thing that I really=20
_don't_ like is the fact that an attempt to access a non-existent list=20
item silently returns nil, rather than throwing an exception. Is there a= =20
way to make this more strict? Hashes have the same behavior, but since=20
they can be assigned a default block, that isn't nearly so much of a=20
problem.
=20
I know I could change List behavior, but there are very obvious reasons= =20
why that's a Bad Thing. I could also subclass list, but then I miss all= =20
of the syntactic niceties of lists. And both solutions impose an extra=20
level of calling for what will be very frequent actions.
=20
Any thoughts welcome,

Since you asked.. :)

We have managed to make do without Array access raising exceptions.

I would REALLY recommend leaving behind the baggage of any previous
languages and take a head-first plunge. In Ruby, Array access returns
a nil if the index is not found. Embrace it! Form your code around the
Ruby idioms, not the other way around!

The payoff will be much greater.

--0NB0lE7sNnW8+0qW
Content-Type: application/pgp-signature
Content-Disposition: inline

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

iD8DBQFFLxST7Nh7RM4TrhIRAjpEAKCQekkcNy/tTJzz3MxSz4kkugUdpQCeMPmc
kkOnmdXhHvQisA5lAw49GpA=
=AUNS
-----END PGP SIGNATURE-----

--0NB0lE7sNnW8+0qW--
 
K

Kenneth McDonald

Yep, got that one. Unfortunately, there's no equivalent for lists.
Actually, I'm going to make another post on this in the next few minutes.
 
K

Kenneth McDonald

Eero said:
Since you asked.. :)

We have managed to make do without Array access raising exceptions.

I would REALLY recommend leaving behind the baggage of any previous
languages and take a head-first plunge. In Ruby, Array access returns
a nil if the index is not found. Embrace it! Form your code around the
Ruby idioms, not the other way around!

The payoff will be much greater.
Certainly possible. I'm not uncomfortable with new ways of doing things
(I really like Ruby iteration, for example), I'm just worried this
difference might cause hard-to-find errors. But I just posted that as a
more general question, so 'nuff said here :)
 
A

ara.t.howard

Certainly possible. I'm not uncomfortable with new ways of doing things (I
really like Ruby iteration, for example), I'm just worried this difference
might cause hard-to-find errors. But I just posted that as a more general
question, so 'nuff said here :)


it's not that hard if you want, and you only need modify the array's you desire
- not all of them in you program:

harp:~ > cat a.rb
class Array
module BoundsCheck
def [] a, *b
b = b.shift
max =
case a
when Numeric
a
when Range
a.exclude_end? ? (a.end-1) : e.end
else
b
end
raise IndexError, max.to_s if max > (size - 1)
super
end
end

def bounds_check!
extend BoundsCheck
end
end

array = %w[ 0 1 2 ]

4.times{|i| puts "array[#{ i }] : #{ array.inspect }"}

array.bounds_check!

4.times{|i| puts "array[#{ i }] : #{ array.inspect }"}



harp:~ > ruby a.rb
array[0] : "0"
array[1] : "1"
array[2] : "2"
array[3] : nil
array[0] : "0"
array[1] : "1"
array[2] : "2"
a.rb:15:in `[]': 3 (IndexError)
from a.rb:31
from a.rb:31


to be robust you'd want to wrap Array#slice and other 'index-y' methods.

regards.

-a
 
J

James Edward Gray II

Yep, got that one. Unfortunately, there's no equivalent for lists.
array, hash = Array.new, Hash.new => [[], {}]
array.fetch(999)
IndexError: index 999 out of array
from (irb):2:in `fetch'
from (irb):2
from :0IndexError: key not found
from (irb):3:in `fetch'
from (irb):3
from :0

James Edward Gray II
 
K

Kenneth McDonald

James said:
Yep, got that one. Unfortunately, there's no equivalent for lists.
array, hash = Array.new, Hash.new => [[], {}]
array.fetch(999)
IndexError: index 999 out of array
from (irb):2:in `fetch'
from (irb):2
from :0IndexError: key not found
from (irb):3:in `fetch'
from (irb):3
from :0

James Edward Gray II
Sorry, shoulda phrased more clearly; there's no solution that checks
indexing on all the various list ops that uses indexing.

It doesn't really matter, from what's been said, this doesn't seem to be
a major issue when programming in Ruby.
 

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

Staff online

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top