如何在Ruby中创建IO的自定义子类?

时间:2009-05-10 10:41:45

标签: ruby

如何制作我自己的可替代IO的类,以便例如某些接受IO类参数的代码的重定向/捕获输入/输出? IO本身似乎与操作系统文件描述符耦合,我所知道的唯一一个模仿它而没有子类化的类是StringIO,它似乎只是重新实现了整个界面。

我认为这种语言会提供一种直接的方式,但我找不到有关该主题的任何信息。是否有一个mixin在几个原语之上实现接口,就像Enumerable一样?

2 个答案:

答案 0 :(得分:4)

我怀疑我错过了一些东西,但假设情况并非如此......

为什么子类化不是一个选项?您是否可以覆盖需要表现不同的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

如果你不能替换你的家庭酿造子类,那么修改IO本身(“猴子修补”)会是这样的:

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 :(得分:1)

我已成功使用以下hack使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