This week I’m looking at Facets’ Array extensions. Hash, Array, String, and Integer objects are used frequently in Rails so I can take advantage of them faster than more complex classes.
The Code
1 2 3 4 5 6 7 8 9 |
# File lib/core/facets/array/pad.rb, line 14 def pad(len, val=nil) return dup if self.size >= len.abs if len < 0 Array.new((len+size).abs,val) + self else self + Array.new(len-size,val) end end |
Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
#!/usr/bin/ruby -wKU # # Code Reading #6 require '../base' require "facets/array/pad" class Example def self.create last_ten_transactions = [ 52.25, 100.25, 0.45 ] last_ten_transactions.pad(10, 0) end end ap Example.create class ArrayPadTest < Test::Unit::TestCase def test_should_pad_the_array_to_10_elements result = Example.create assert_equal 10, result.length end def test_should_pad_to_the_end_of_the_array result = Example.create assert_equal [ 52.25, 100.25, 0.45, 0, 0, 0, 0, 0, 0, 0 ], result end end |
Review
Array#pad
‘s concept is pretty easy to understand, since padding is used with strings a lot. The implementation is a bit terse so I’ll break it up a little bit to help understanding. Array#pad
has three different exit conditions:
- The array is already bigger than the padding.
-
#pad
is called with a positive padding length. -
#pad
is called with a negative padding length.
The first exit condition is from the guard clause, return dup if self.size >= len.abs
. The reason it’s using dup is because Array#pad
is returning a new array for all the other conditions. If this case was different, the caller might accidentally use the Array without knowing that’s it’s the same Array they passed in.
The second exit condition is when #pad
is called with a positive padding length. This will create a new array that is prepopulated with val
and append it to the calling array, making sure the total length is equal to the len
.
The third exit condition is when #pad
has a negative padding length. Like before it creates a new array that is prepopulated with val
, but this time it prepends the new array onto the calling array.
Prepopulate an Array with values
To prepopulate an array with values, just pass the size and value to Array#new
. It can also take a block if you need something more dynamic:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
>> Array.new(10, 'ten element array') [ [0] "ten element array", [1] "ten element array", [2] "ten element array", [3] "ten element array", [4] "ten element array", [5] "ten element array", [6] "ten element array", [7] "ten element array", [8] "ten element array", [9] "ten element array" ] >> Array.new(10) { rand(100) } [ [0] 93, [1] 11, [2] 81, [3] 84, [4] 14, [5] 16, [6] 6, [7] 40, [8] 77, [9] 88 ] |