我正在创建一个类似于数组的对象,但需要在将项目添加到数组之前进行一些数据初始化。
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/