类似unix的管道的ruby简单实现代码简单说明

来源:互联网 发布:mac 黑苹果安装驱动 编辑:程序博客网 时间:2024/06/05 19:04

此代码来自此处


class PipelineElement   attr_accessor :source   def initialize      @fiber_delegate = Fiber.new do         process      end   end   def |(other)      other.source = self      other   end   def resume      @fiber_delegate.resume   end   def process      while value = input         handle_value(value)      end   end   def handle_value(value)      output(value)   end   def input      @source.resume   end   def output(value)      Fiber.yield(value)   endendclass Producer < PipelineElement   def process     while true       value=readline.chomp       handle_value(value)     end   endendclass Filter < PipelineElement  def initialize    @line=1    super()  end  def handle_value(value)    value=sprintf("%5d %s",@line,value)    output(value)    @line=@line.succ  endendclass Consumer < PipelineElement  def handle_value(value)    puts value  endendproducer=Producer.newfilter=Filter.newconsumer=Consumer.newpipeline = producer | filter | consumerpipeline.resume

打印pipeline对象得到如下输出:

#<Consumer:0x8f08bf4 @fiber_delegate=#<Fiber:0x8f08a88>, @source=#<Filter:0x8f08db4 @line=1, @fiber_delegate=#<Fiber:0x8f08d60>, @source=#<Producer:0x8f09054 @fiber_delegate=#<Fiber:0x8f09038>>>>


PipelineElement段代码非常巧妙,将Fiber和Ruby的功能完全展示了出来。

producer=Producer.newfilter=Filter.newconsumer=Consumer.new
此段将纤程挂起,再使用
pipeline = producer | filter | consumer

依次调用|重载函数,最终返回consumer对象,其中|函数将把实例赋给other(即:|后的参数)的source属性

使用

pipeline.resume
运行consumer纤程,consumer执行process函数

  def process      while value = input         handle_value(value)      end   end
接下来调用父类的input函数跳到filter纤程,于是开始执行filter纤程的process,进而唤醒producer执行process,输入value并且handle_value,从而将value传回filter纤程的value,filter纤程接手handle_value

 def handle_value(value)    value=sprintf("%5d %s",@line,value)    output(value)    @line=@line.succ  end
再通过output将处理好的value传回consumer并且转回consumer纤程,consumer继续handle_value


  def handle_value(value)    puts value  end

此时输出value,同时开始下一次while循环,同时也开始了下一次连续的纤程循环。

另外从打印出来的pipeline可以很清楚的看到此过滤链的层次:

#<Consumer:0x8f08bf4 @fiber_delegate=#<Fiber:0x8f08a88>, @source=#<Filter:0x8f08db4 @line=1, @fiber_delegate=#<Fiber:0x8f08d60>, @source=#<Producer:0x8f09054 @fiber_delegate=#<Fiber:0x8f09038>>>>




原创粉丝点击