Skip to content

Instantly share code, notes, and snippets.

@emasaka
Created September 29, 2014 05:05
shell-like pipeline in Ruby DSL
#!/usr/bin/env ruby
module PipeOperator
refine Array do
def |(x)
PipeLine.new(self) | x
end
end
end
class PipeLine
def initialize(cmd)
@cmds = [cmd]
end
def |(cmd)
@cmds << cmd
self
end
def execute
cmds = @cmds
# copied from http://tmtms.hatenablog.com/entry/2013/10/09/sheru
pipes = Array.new(cmds.count-1){IO.pipe}
pipes = [nil, pipes.flatten.reverse, nil].flatten
cmds.each do |cmd, *args|
r, w = pipes.shift 2
pid = Process.fork do
STDIN.reopen r if r
STDOUT.reopen w if w
Process.exec [cmd, cmd], *args
end
r.close if r
w.close if w
end
Process.waitall
end
def self.run
yield.execute
end
end
if __FILE__ == $0
using PipeOperator
PipeLine::run { ['yes', 'Yo!'] | ['nl'] | ['head', '-n', '10'] }
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment