ruby - 如何用自定义对象包装 Ruby 数组,但支持与数组相同的方法?

标签 ruby

我正在创建一个类似于数组的对象,但需要在将项目添加到数组之前进行一些数据初始化。

class People
  def initialize(data_array)
    @people_array = data_array.map {|data| Person.new(data) }
  end

  def <<(data)
    @people_array << Person.new(data)
  end

  # def map(&block) ...
  # def each(&block) ...
  # etc...
end

我想支持数组支持的所有相同方法并委托(delegate)给这些方法,这样我就不必重写所有这些方法。实现这一目标的最简单/最干净的方法是什么?

最佳答案

也许继承了Array类是一个很好的解决方案:

class People < Array
  def initialize(data_array)
    super(data_array.map {|data| Person.new(data) })
  end

  def <<(item)
    super(Person.new(item))
  end
end

但是,如评论和 axel 的回答中所述,它有一些缺点。

另一种解决方案是组合和混合:

class People
  include Enumerable
  
  def initialize(data_array)
    @collection = data_array.map {|data| Person.new(data) }
  end

  def each(&block)
    @collection.each(&block)
  end
  
  def <<(data)
    @collection << Person.new(data)
  end
end

但是,此解决方案只为您提供 Enumerable 提供的方法模块,以及 <<运营商。

查看Array有什么方法自己定义,很容易做到:

(Array.instance_methods - (Enumerable.instance_methods + Object.instance_methods)).sort
 => [:&, :*, :+, :-, :<<, :[], :[]=, :assoc, :at, :bsearch, :clear, :collect!,
 :combination, :compact, :compact!, :concat, :delete, :delete_at, :delete_if, :each,
 :each_index, :empty?, :fetch, :fill, :flatten, :flatten!, :index, :insert, :join,
 :keep_if, :last, :length, :map!, :pack, :permutation, :pop, :product, :push, :rassoc,
 :reject!, :repeated_combination, :repeated_permutation, :replace, :reverse, :reverse!,
 :rindex, :rotate, :rotate!, :sample, :select!, :shift, :shuffle, :shuffle!, :size, :slice,
 :slice!, :sort!, :sort_by!, :to_ary, :transpose, :uniq, :uniq!, :unshift, :values_at, :|]

但是我认为这是一个肮脏的解决方案,并鼓励使用 Axel's answer .

关于ruby - 如何用自定义对象包装 Ruby 数组,但支持与数组相同的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31861322/

相关文章:

Ruby `ensure` 未运行

ruby - 使用 rspec 在 Controller 中 stub API 调用

ruby - Rails 6.1.1 不会在生产模式下加载 webpacker 创建的 CSS 文件

ruby - 为什么 'Date.parse' 不引发无效日期字符串的异常?

ruby-on-rails - 在 Rails 中子类化用户模型真的很糟糕吗?

ruby - Jekyll 无法在 Manjaro Linux 上部署 - Sass-Listen-4.0.0 无法在部署时安装(GitLab、Netlify)

Ruby Regex 舍入尾随零

ruby-on-rails - 名称已被 Ruby on Rails 使用或保留?

ruby-on-rails - unicorn 从配置开始失败

ruby-on-rails - ruby 中的哈希和函数参数