0

I have a class CustomArray:

class CustomArray < Array
  def initialize(row, col)
    @row = row
    @col = col
    @array ||= Array.new(size=row * col)
  end
end

How can I override the []= method of CustomArray? I did:

class CustomArray < Array
  def []=(length, row, col)
    puts @array[0], col, row
  end
end

Regardless of a change I make to @array, the new instantiated array length remains zero.

I tried replacing the value of self, but it looks like self is read only.

2
  • I don't understand your question. First you ask "How to override the []= method?", but you already know the answer - you've done it in the code sample. Then to talk about instantiating a new class instance... What does this mean, exactly? Can you provide an example of where you are creating a new instance, and explain what behaviour you'd like/expect? And then you talk about "replacing the value of self"... For a start, that's not possible (an object cannot change which object it is!) - but again, I don't really know what you mean since there's no code sample or explanation. Commented Oct 29, 2018 at 9:38
  • 3
    Perhaps it would be more helpful if you were to explain what it is you're trying to achieve, not how you're trying to do it. This question seems like a probable XY problem to me - it seems you're stuck with an unusual implementation, which could possibly be solved in a much simpler way. Commented Oct 29, 2018 at 9:40

1 Answer 1

4

You don't need an @array instance variable when subclassing Array – each instance already is an array.

Assuming that you are trying to implement a two-dimensional array on top of the build-in (one-dimensional) Array, something like this should work:

class CustomArray < Array
  def initialize(rows, cols)
    @rows = rows
    @cols = cols
    super(rows * cols)
  end

  def []=(row, col, value)
    super(row * @rows + col, value)
  end

  def [](row, col)
    super(row * @rows + col)
  end
end

However, Ruby's core classes are heavily optimized and subclassing them can be quite tricky (see https://words.steveklabnik.com/beware-subclassing-ruby-core-classes).

Therefore, it's usually easier to use composition instead of inheritance, i.e. do use an @array instance variable, but don't inherit from Array, e.g.:

class CustomArray
  def initialize(rows, cols)
    @rows = rows
    @cols = cols
    @array = Array.new(rows * cols)
  end

  def []=(row, col, value)
    @array[row * @rows + col] = value
  end

  def [](row, col)
    @array[row * @rows + col]
  end
end
Sign up to request clarification or add additional context in comments.

3 Comments

...Or perhaps it would be more practical to use ruby's standard library Matrix implementation? It all depends what was trying to be achieved in the first place.
@TomLord although Matrix is tailored towards mathematical matrices, not two-dimensional arrays (or arrays of arrays) in general.
Excellent answer! @Tom, the fact that matrix objects are immutable may be another limitation.

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.