在Ruby数组中重写`[] =`方法

时间:2018-10-29 09:10:10

标签: ruby

我有一个CustomArray班:

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

如何覆盖[]=的{​​{1}}方法?我做到了:

CustomArray

无论我对class CustomArray < Array def []=(length, row, col) puts @array[0], col, row end end 进行什么更改,新的实例化数组长度都保持为零。

我尝试替换@array的值,但看起来self是只读的。

1 个答案:

答案 0 :(得分:3)

子类化@array时,您不需要Array实例变量–每个实例都是一个数组。

假设您尝试在内置{一维} Array之上实现二维数组,则类似这样的方法应该起作用:

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

但是,Ruby的核心类已经过大量优化,对其进行子类化非常棘手(请参见https://words.steveklabnik.com/beware-subclassing-ruby-core-classes)。

因此,使用合成而不是继承通常更容易,即使用@array实例变量,但不要从Array继承,例如:

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