Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
class TwoWayPipe
attr_reader :pull, :push
def initialize
@pull, @push = IO.pipe
end
end
class PipeProcess
def self.start(command, last_pipe = TwoWayPipe.new, original_pipe = last_pipe)
new(command, last_pipe, original_pipe)
end
attr_reader :original_pipe
def initialize(command, last_pipe, original_pipe)
@original_pipe = original_pipe
pipe = TwoWayPipe.new
fork do
pipe.push.close
STDOUT.reopen(last_pipe.push)
STDIN.reopen(pipe.pull)
exec command
end
@pipe = pipe
end
def read
@original_pipe.push.close
@original_pipe.pull.read
end
def pipe(command)
self.class.start(command, @pipe, @original_pipe).tap do
@pipe.push.close
end
end
end
class ReversePipeProcess
def initialize(command, last_process = nil)
@command, @last_process = command, last_process
end
def pipe(command)
self.class.new(command, self)
end
def commands
commands = []
commands << @command
commands.concat(@last_process.commands) if @last_process
commands
end
def read
list = commands
first = PipeProcess.start(list.shift)
list.inject(first) {|process, command| process.pipe(command) }.read
end
end
module Kernel
def pipe(command)
ReversePipeProcess.new(command)
end
end
puts pipe("ls").pipe("grep Adium").pipe("grep 'Update 1'").read
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment