Как создать собственный подкласс IO в Ruby? - PullRequest
9 голосов
/ 10 мая 2009

Как мне создать свой собственный класс, который можно заменить на IO, например, для перенаправить / захватить ввод / вывод для некоторого кода, который принимает IO-подобный параметр? Похоже, что сам IO связан с файловыми дескрипторами ОС, и единственный известный мне класс, имитирующий его без подклассов, - это StringIO, который, кажется, просто переопределяет весь интерфейс.

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

Ответы [ 2 ]

4 голосов
/ 10 мая 2009

Я подозреваю, что что-то упустил, но предположим, что это не так ...

Почему не может быть подклассов? Не могли бы вы просто переопределить части IO, которые должны вести себя по-другому?

class MyIO < IO
  # your modified methods go here. e.g.
  def some_io_method(args)
    do_some_preprocessing
    super(args)
    do_some_post_processing
  end
end

Если вы не можете заменить свой подкласс домашнего варки, как насчет изменения самого ввода-вывода («мартышка-патчинг») примерно так:

class IO
  alias_method :original_some_io_method, :some_io_method
  def some_io_method(args)
    do_some_preprocessing
    original_some_io_method(args)
    do_some_post_processing
  end
end
1 голос
/ 13 августа 2009

Я успешно использовал следующий хак, чтобы сделать StringIO «настоящим» IO:

    # make mechanize believe our address xml actually is an IO so it will be uploaded as a file:
    address_io = StringIO.new(address_xml)
    class << address_io
      alias is_a_old is_a?
      def is_a?(stuff)
        stuff == IO || is_a_old(stuff)
      end
      def path
        'address.xml'
      end
    end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...