Tuesday, July 6, 2010

Augmented Array in Ruby

Few days ago, I was randomly going through the Ruby Array class API and the method '*' caught my attention.

array * int -> an_array : Returns a new array built by concatenating the int copies of self.

[ 1, 2, 3 ] * 3 #=> [ 1, 2, 3, 1, 2, 3, 1, 2, 3 ]

I just had a thought can I have a method named '/' which will return a new array by splitting the array into arrays of int divisor elements each ?

The functionality that I was looking for :-

[1,2,3,4,5,6]/1 # => [[1], [2], [3], [4], [5], [6]]
[1,2,3,4,5,6]/2 # => [[1, 2], [3, 4], [5, 6]]
[1,2,3,4,5,6]/3 # => [[1, 2, 3], [4, 5, 6]]

I gave it a try, my fingers typed the code as per my brain's instructions and it worked the way I expected.

Then I saw the methods at(index) and fetch(index) and thought can I fetch or even set the elements of the array with the index as if index acting as array's attributes ?

Like this :-

ary = [1,2,3]
ary._0 = 25
ary._0 # => 25
ary._1 = 10
ary._1 # => 10
ary # => [25, 10,3]

For the above to work, I played with the method_missing method.

Few things that I noticed in the Array class were it has 'first' and 'last' methods but not 'first=' and 'last=' methods. It has 'nitems' method which returns the number of non-nil elements, but no 'nilitems' method which will return nil elements in the array.

My mind started to think whether I can build some other useful methods as well and it came to a sufficiently big list which I finally moved into a gem. I named the gem as 'augmented_array' and pushed it to gemcutter.

Install:
====
gem install augmented_array

Uninstall:
====
gem uninstall augmented_array

Source Code is available at my Github repository.

2 comments:

  1. Very cool stuff, Niranjan.

    I love the idea of collecting useful methods like these together into a single gem package. The next time I think the Array class is missing something I’ll take a look here to see if you’ve already built it. And if not maybe I’ll fork your repo and add a method or two.

    It also seems like some of the same methods could apply to Hash or other Ruby objects. I wonder if it’s worth exploring extending those objects as well? And would the same method names make sense?

    ReplyDelete
  2. Thanks Pat !
    It's really a good idea exploring extending other ruby objects with some useful methods. Ya... and we might need to think about generic method names that will apply for most of the objects. For some cases, the names may differ.

    You are most welcome to augment this repo to make it more powerful and useful !

    Thanks.

    ReplyDelete