Maybe inheriting the Array class is a good solution:
class People < Array
def initialize(data_array)
super(data_array.map {|data| Person.new(data) })
end
def <<(item)
super(Person.new(item))
end
end
However, it has some disadvantages as mentioned in the comments and in axel's answer.
An alternative solution is composition and mixins:
class People
include Enumerable
def initialize(data_array)
@collection = data_array.map {|data| Person.new(data) }
end
def each(&block)
@collection.each(&block)
end
def <<(data)
@collection << Person.new(data)
end
end
However, this solution only gives you methods provided by the Enumerable module, along with the << operator.
To see what methods the Array itself defines, easily do:
(Array.instance_methods - (Enumerable.instance_methods + Object.instance_methods)).sort
=> [:&, :*, :+, :-, :<<, :[], :[]=, :assoc, :at, :bsearch, :clear, :collect!,
:combination, :compact, :compact!, :concat, :delete, :delete_at, :delete_if, :each,
:each_index, :empty?, :fetch, :fill, :flatten, :flatten!, :index, :insert, :join,
:keep_if, :last, :length, :map!, :pack, :permutation, :pop, :product, :push, :rassoc,
:reject!, :repeated_combination, :repeated_permutation, :replace, :reverse, :reverse!,
:rindex, :rotate, :rotate!, :sample, :select!, :shift, :shuffle, :shuffle!, :size, :slice,
:slice!, :sort!, :sort_by!, :to_ary, :transpose, :uniq, :uniq!, :unshift, :values_at, :|]
However I would consider this a dirty solution, and would encourage going with Axel's answer.
People#flatten,People#freeze,People#slice,People#fill, andPeople#packare quite interesting.Peopleas an example. It's called something else in my app. But that's funny. =]