В следующем коде проблема заключается в том, что после вызова метода .find_name для типа объекта LogsCollection возвращаемый объект становится собственным массивом и не остается типом LogsCollection. Я считаю, что правильный подход может заключаться в создании конструктора / инициализатора, который принимает массив и возвращает новый объект правильного типа. Но я не уверен, что нет лучшего способа сделать это?
Может ли Ruby-pro-eye взглянуть на этот код и предложить (на уровне кода) лучший способ сделать возвращаемый объект из .find_name сохраняющим тип LogsCollection (не массив)?
class Log
attr_accessor :name, :expense_id, :is_excluded, :amount, :paid_to
def initialize(name, expense_id, is_excluded, amount, paid_to)
@name = name
@expense_id = expense_id
@is_excluded = is_excluded
@amount = amount
@paid_to = paid_to
end
end
class LogsCollection < Array
def names
collect do |i|
i.name
end
end
def find_name(name)
@name = name
self.select { |l| l.name == @name }
end
end
logs = LogsCollection.new
logs.push(Log.new('Smith', 1, false, 323.95, nil))
logs.push(Log.new('Jones', 1, false, 1000, nil))
logs = logs.find_name('Smith')
puts logs.count
unless logs.empty?
puts logs.first.name # works since this is a standard function in native array
puts logs.names # TODO: figure out why this fails (we lost custom class methods--LogsCollection def find_name returns _native_ array, not type LogsCollection)
end
Финальный код пост-ответа для всех, кто ищет (обратите внимание на удаление базового класса <массив): </p>
class Log
attr_accessor :name, :expense_id, :is_excluded, :amount, :paid_to
def initialize(name, expense_id, is_excluded, amount, paid_to)
@name = name
@expense_id = expense_id
@is_excluded = is_excluded
@amount = amount
@paid_to = paid_to
end
end
class LogsCollection
attr_reader :logs
def initialize(logs)
@logs = logs
end
def add(log)
@logs.push(log)
end
def names
@logs.collect { |l| l.name }
end
def find_name(name)
LogsCollection.new(@logs.select { |l| l.name == name })
end
end
logs = LogsCollection.new([])
logs.add(Log.new('Smith', 1, false, 323.95, nil))
logs.add(Log.new('Jones', 1, false, 1000, nil))
puts logs.names
puts '--- post .find_name ---'
puts logs.find_name('Smith').names