Skip to content

Instantly share code, notes, and snippets.

@wayneeseguin
Forked from wycats/itworks.rb
Created December 18, 2009 05:23
Show Gist options
  • Save wayneeseguin/259311 to your computer and use it in GitHub Desktop.
Save wayneeseguin/259311 to your computer and use it in GitHub Desktop.
# Added small readability tweak
# input/output instead of pull/push
class TwoWayPipe
attr_reader :input, :output
def initialize
@input, @output = 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.output.close
STDOUT.reopen(last_pipe.output)
STDIN.reopen(pipe.input)
exec command
end
@pipe = pipe
end
def read
@original_pipe.output.close
@original_pipe.input.read
end
def pipe(command)
self.class.start(command, @pipe, @original_pipe).tap do
@pipe.output.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