3

Say I have a custom class, what should I override to get array-like behaviour? I think that supplying an each method won't be enough, as that won't give me acces to the [] methods?

Should I inherit the Array class? What should I overwrite in there?

1
  • 1
    Congrats for wanting to do it the right way around. Too many people first think of monkey-patching array to add their custom functionality. Commented Jun 5, 2011 at 1:23

3 Answers 3

7

For enumerable like behavior (which sounds like what you want), you should include Enumerable to get the Enumerable module functionality, which means you need to provide a method each. This will give you lots of the relevant methods you want (Enumerable details).

If you want just [] like functionality, you only need the following methods, and nothing more:

def [] key
  # return value for key here.
end

def []= key, value
  # store value under key here.
end
Sign up to request clarification or add additional context in comments.

4 Comments

An array providers both [] methods, and enumerable functionality. So maybe I should consider adding both each and these 2 accessor methods?
Yep, if that's what you're after then provide each, [], []= and include Enumerable.
Is there any advantage of this approach vs. subclassing Array?
It depends. Can you say that "<your object> is an Array?" If so, make it a subclass of the Array, because you need all that functionality. If all you can say is "<your object> is like an array in some ways, because it supports []", then just support [] and don't subclass.
2

Inheriting from Array makes perfect sense. You get to extend Array behavior without worrying about interactions with other users of the Array type, and you don't even need to do the trivial work to mix in Enumerable.

And if you need hooks, which you probably do, you can just call super() to forward the current message.

Comments

1

If you have an actual array that stores your data, you may want to have

require "forwardable"

class CustomArray
  extend Forwardable # For def_delegators
  include Enumerable # Optional

  def_delegators :@actual_array, :[], :[]=, :each

  def initialize(actual_array)
    @actual_array = actual_array
  end
end

By using delegation, you only provide the methods that you know you want, rather than providing all the methods by default.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.