Как обернуть массив определенным подклассом Enumerator?

Я создал подкласс Enumerator с несколькими специальными свойствами (т.е. он знает, что его элементы являются объектами времени):

class TimedEnumerator < Enumerator
  ...some time-specific methods...
end

Учитывая массив объектов Time, как создать TimedEnumerator? Моя первая мысль заключалась в том, чтобы просто использовать метод ::new, но это генерирует предупреждение об устаревании:

>> TimedEnumerator.new(array)
(irb):12: warning: Enumerator.new without a block is deprecated; use Object#to_enum

И, конечно же, array.to_enum создает объект Enumerator, а не объект TimedEnumerator.

Как правильно это сделать?


person fearless_fool    schedule 07.11.2013    source источник
comment
В общем, я бы полностью избегал этого, так как вам нужно будет переопределить основной метод Object. Я думаю, что более простой способ сделать это - обернуть перечислитель в класс декоратора, который реализует ваши методы, зависящие от времени, но все же делегирует обратно перечислителю для стандартного поведения.   -  person Zach Kemp    schedule 07.11.2013
comment
@ZachKemp: полностью избегая этого, я полагаю, вы имеете в виду изменить .to_enum? Я согласен. Не уверен, что вы имеете в виду более простой способ. Есть пример?   -  person fearless_fool    schedule 08.11.2013


Ответы (1)


Я смог создать подкласс Enumerator, сделав это:

class TimedEnumerator < Enumerator
  def initialize(array)
    super() do |array|
      #your logic
    end
  end 
end

TimedEnumerator.new(array)
#=> <TimedEnumerator: #<Enumerator::Generator:0x007ff4cb89a9f0>:each>

Нашел трюк super() отсюда: ArgumentError in #new, перечислитель подклассов.

person Josh    schedule 07.11.2013
comment
Имейте в виду, все, что я хочу, это сделать эквивалент TimedEnumerator.new(array), но без предупреждения об устаревании. Я не пытаюсь воздействовать на массив в методе .new, я просто хочу, чтобы он был заключен в мой подкласс Enumerator. - person fearless_fool; 08.11.2013