Avatar

The problem with this code is that it breaks if a is not defined

And it has undesirable results if a is not an array

Any ideas how to make it more robust without lots of if-then-else?

1
v = a[:k][0]  ||  1

Refactorings

No refactoring yet !

0c39b828636367fc6e22b7be8c803c74

David Calavera

July 22, 2008, July 22, 2008 11:15, permalink

No rating. Login to rate!
1
a ||= {} ; a[:k] ||= []; v = a[:k][0]  ||  1
92772ff5353c89d9bd10f8e334161e16

Ben Hughes

July 22, 2008, July 22, 2008 11:44, permalink

No rating. Login to rate!

A little crude, but works...

1
a = a[:k][0] || 1 rescue 1
0176d9564601b43d75aff59f2cceed88

Markus Prinz

July 22, 2008, July 22, 2008 11:45, permalink

2 ratings. Login to rate!

You could also make the default values for the Hash and the Array simply return appropriate objects. But depending on how the rest of your program looks, this could have unintended side-consequences.

1
2
3
4
a = Hash.new{|h,k| h[k] = Array.new { nil } }

a[:k] # => []
a[:k][0] # => nil
2fa67a053f1bb83dca069df3c9f51a8a

lel

July 22, 2008, July 22, 2008 14:15, permalink

No rating. Login to rate!

The above Hash.new can be made prettier. (edit: The reply below is correct, I was so into usage like Hash.new(0) -- where the default object isn't directly modified, unlike an array which often is)

1
2
3
4
5
6
a ||= Hash.new([])  # default value for non-existing keys is now an empty array, unless a was already defined

a[:k] # => []
a[:k][0] # => nil

v = a[:k][0] || 1
0176d9564601b43d75aff59f2cceed88

Markus Prinz

July 22, 2008, July 22, 2008 16:34, permalink

1 rating. Login to rate!

Actually you have to be careful with "Hash.new([])", because the hash is going to return that exact same array for every key it doesn't already store. So you should still use the Hash.new with a block. The Array.new isn't necessary though.

1
2
3
4
5
6
7
8
9
h = Hash.new([])
h[:a].object_id # => 9762120
h[:b].object_id # => 9762120
h[:a] << "test" # => ["test"]
h[:b] # => ["test"]


# Thus:
a = Hash.new{|h,k| h[k] = [] } # This ensures that a new Array is generated every time an unknown key is accessed
Bfec5f7d1a4aaafc5a2451be8c42d26a

macournoyer

July 22, 2008, July 22, 2008 20:58, permalink

No rating. Login to rate!
1
v = (a[:k][0] rescue nil) || 1
5071c5b861341c0dcfcf6ac86327701f

Tien Dung

July 23, 2008, July 23, 2008 02:37, permalink

No rating. Login to rate!

More like JavaScript style

1
2
3
4
5
a ||= {} ; a[:k] ||= []; v = a[:k][0]  ||  1

# change to

v = a || a[:k] || a[:k][0] || 1

Your refactoring





Format Copy from initial code

or Cancel