如何在Ruby中覆盖Array Constructor?

时间:2016-09-25 21:00:00

标签: ruby oop

我有以下课程:

Couldn't match expected type `t -> [(a, b)]'
            with actual type `Struct'
Relevant bindings include
  xs :: t (bound at bbox.hs:15:9)
  results :: t -> [(a, b)] (bound at file.hs:15:1)
The function `substructs' is applied to one argument,
but its type `Struct' has none
In the second argument of `sortBy', namely `(substructs xs)'
In the expression: sortBy (compare `on` fst) (substructs xs)

我想在类的构造函数中初始化authors属性,并仍然使用Array#new行为。我试过这个:

class Library < Array
  attr_accessor :authors
end

但这会产生错误。

我怎样才能做到这一点?

1 个答案:

答案 0 :(得分:2)

因此#initialize覆盖失败,因为您正在使用对象splat(**)而不是数组splat(*)。

但你不应该这样做。对Ruby的核心类进行子类化将导致各种反直觉行为,因为它们有许多方法可以创建该类的新实例 - 这些方法不会更新以创建类的新实例。例如,Library.new.reverseLibrary.new + Library.new都将返回新数组,而不是库。

相反,您可以通过在类中创建数组实例变量并委派给它来获得所需的行为。您可以定义#each并获取所有Ruby enumerable方法。您还可以定义所需的任何数组方法。

class Library
  include Enumerable
  attr_accessor :authors

  def initialize(*args)
    @authors = {key1: 'val1', key2: 'val2'}
    @array = args
  end

  def each(&block)
    @array.each(&block)
  end

  def [](index)
    @array[index]
  end
end