Perl is pretty nice about default values:
: jmglov@laurana; perl -e \'@foo; printf \"%d\\n\", $foo[123]\'
0
: jmglov@laurana; perl -e \'%foo; printf \"%d\\n\
I think an array is the wrong abstraction if you want to auto extend the array. Add another level of abstraction.
Edit (from our discussion): The important thing is that the code to achieve your goal is located in the right place (single responsibility principle), and that place is not your "client code", hence the need for a new class. Extending the existing Array class (through inheritance/mixin) is probably better than encapsulating the wanted behaviour in an entierly new class.
Not auto extended, but initialized to the specified length with a default value:
>> Array.new(123, 0)
=> [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
I'll put Johans elegant solution out there: foo.compact.inject(:+)
Another approach would be overriding the Array#[]
method and return the default value if there is no item
class Array
def [](index)
self.at(index) ? self.at(index) : 0
end
end
and
arr = [1,2,3]
puts arr[0] # print 1
puts arr[5] # print 0
Given that Ruby returns nil
for a non-existing element (as opposed to index-out-of-bounds type error), you could just use an "or":
a = [1,2,3]
puts a[5] # => nil
puts a[5] || "a default" # => a default
You could take the monkey patch approach, but you probably would not want to do this in anything larger than a 1-file script:
a = [1,2,3]
def a.[](index)
self.at(index) || "a default"
end
puts a[5] # => "a default"
If you're dealing with integers you can call to_i
:
foo = []
foo[100]
#=> nil
foo[100].to_i
#=> 0
foo[100] = 3
foo[100]
#=> 3
UPD
Oh, I didn't read all topic :)
so you can use this:
foo.inject{|a,b| a.to_i + b.to_i }
which, actually, not the smartest one