Active Record, как функциональность в переменной экземпляра массива - PullRequest
2 голосов
/ 10 мая 2010

Я хотел бы написать модуль, обеспечивающий функциональность, подобную активной записи, в переменной экземпляра массива.

Примеры его использования:

x = Container.new
x.include(ContainerModule)
x.elements << Element.new
x.elements.find id

module ContainerModule
   def initialize(*args)
     @elements = []
     class << @elements
        def <<(element)
          #do something with the Container...
          super(element)         
        end

        def find(id)
          #find an element using the Container's id
          self
          #=> #<Array..>  but I need #<Container..>
        end
     end
     super(*args)
  end
end

Проблема в том, что мне нужен объект-контейнер в этих методах. Любая ссылка на себя вернет Array, а не объект Container.

Есть ли способ сделать это?

Спасибо!

Ответы [ 2 ]

1 голос
/ 12 мая 2010

Хотелось бы что-нибудь подобное для вас?

class Container
  attr_accessor :elements

  def initialize
    @elements = ContainerElements.new
  end
end

class ContainerElements < Array

  def find_by_id(id)
    self.find {|g| g.id == id }
  end

end

Итак, я создаю контейнер-класс и ContainerElements, которые наследуются от Array, с добавленным (специфическим) методом find_by_id.Если вы действительно хотите назвать его find, вам нужно alias его.

Пример кода:

class ElemWithId
  attr_accessor :id
  def initialize(value)
    @id = value
  end
end

cc = Container.new
cc.elements << ElemWithId.new(1)
cc.elements << ElemWithId.new(5)

puts "elements = #{cc.elements} "
puts "Finding: #{cc.elements.find_by_id(5)} "

Надеюсь, это поможет ...

0 голосов
/ 10 мая 2010

Наилучшим подходом может быть работа с классом Hash , в котором уже есть такие операции, как поиск по идентификатору. В частности, метод fetch может вам помочь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...