我正在创建一个像数组一样的对象,但在将项添加到数组之前需要进行一些数据初始化。
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
我想支持数组支持的所有相同方法并委托给那些方法,这样我就不必重写所有这些方法。实现这一目标的最简单/最简洁的方法是什么?
答案 0 :(得分:2)
也许继承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, :|]
但是,我认为这是一个肮脏的解决方案,并鼓励使用alex's answer。
答案 1 :(得分:1)
您可以使用Delegator作为
class SimpleDelegator < Delegator
def initialize(obj)
super # pass obj to Delegator constructor, required
@delegate_sd_obj = obj # store obj for future use
end
end
我会劝阻extending Array。
答案 2 :(得分:1)
当然,你总是可以篡改它
class People
def model
@arr ||= []
end
def method_missing(method_sym, *arguments, &block)
define_method method_sym do |*arguments|
model.send method_sym, *arguments
end
send(method_sym, *arguments, &block)
end
#probably should implement respond_to? here
end
我更喜欢这种方法,因为你不会混淆对阵Array和扩展Array的实现。您可以构建自定义匹配器,以仅实现特定的数组方法,例如可用于People类的方法。