Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I add 'each' method to Ruby object (or should I extend Array)?

Tags:

ruby

I have an object Results that contains an array of result objects along with some cached statistics about the objects in the array. I'd like the Results object to be able to behave like an array. My first cut at this was to add methods like this

 def <<(val)     @result_array << val  end 

This feels very c-like and I know Ruby has better way.

I'd also like to be able to do this

 Results.each do |result|        result.do_stuff     end 

but am not sure what the each method is really doing under the hood.

Currently I simply return the underlying array via a method and call each on it which doesn't seem like the most-elegant solution.

Any help would be appreciated.

like image 493
Poul Avatar asked Jan 17 '10 04:01

Poul


People also ask

How do you add to a method in Ruby?

Ruby | Set add() method The add is an inbuilt method in Ruby which adds an element to the set. It returns itself after addition. Parameters: The function takes the object to be added to the set. Return Value: It adds the object to the set and returns self.

How are arrays implemented in Ruby?

Internally Ruby arrays are allocated as C-style arrays of a fixed size and are automatically resized as elements are added. As an optimization they are often re-sized a bit beyond what you need to avoid re-allocating on every single addition.

Does Ruby have arrays?

Ruby arrays are ordered, integer-indexed collections of any object. Each element in an array is associated with and referred to by an index. Array indexing starts at 0, as in C or Java.


1 Answers

For the general case of implementing array-like methods, yes, you have to implement them yourself. Vava's answer shows one example of this. In the case you gave, though, what you really want to do is delegate the task of handling each (and maybe some other methods) to the contained array, and that can be automated.

require 'forwardable'  class Results   include Enumerable   extend Forwardable   def_delegators :@result_array, :each, :<< end 

This class will get all of Array's Enumerable behavior as well as the Array << operator and it will all go through the inner array.


Note, that when you switch your code from Array inheritance to this trick, your << methods would start to return not the object intself, like real Array's << did -- this can cost you declaring another variable everytime you use <<.

like image 138
Chuck Avatar answered Oct 11 '22 10:10

Chuck