Skip to content

Instantly share code, notes, and snippets.

@jakecoffman
Created January 9, 2015 16:11
Show Gist options
  • Save jakecoffman/a307d6dd754f7612f2de to your computer and use it in GitHub Desktop.
Save jakecoffman/a307d6dd754f7612f2de to your computer and use it in GitHub Desktop.
Unix-y pipelines in Go (functional programming)
package main
import (
"bufio"
"fmt"
"log"
"os"
"runtime"
"strings"
)
func main() {
Run(Cat("testfile.txt"), Grep("model"), Stdout())
}
type Comms struct {
Tx chan<- string
Rx <-chan string
}
func Run(comms ...Comms) {
for i := 0; i < len(comms); i++ {
if i+1 < len(comms) {
go func(inComm, outComm Comms) {
defer close(outComm.Tx)
for line := range inComm.Rx {
outComm.Tx <- line
}
}(comms[i], comms[i+1])
} else {
for _ = range comms[i].Rx {
}
}
}
}
func Cat(filename string) Comms {
file, err := os.Open(filename)
if err != nil {
log.Fatal(err)
}
out := make(chan string)
go func() {
defer func() {
file.Close()
close(out)
}()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
out <- scanner.Text()
}
if err := scanner.Err(); err != nil {
log.Fatal(err)
}
}()
return Comms{nil, out}
}
func Grep(grep string) Comms {
in := make(chan string)
out := make(chan string)
go func() {
defer close(out)
for line := range in {
if strings.Contains(line, grep) {
out <- line
}
}
}()
return Comms{in, out}
}
func Stdout() Comms {
in := make(chan string)
out := make(chan string)
go func() {
defer close(out)
for line := range in {
fmt.Println(line)
}
}()
return Comms{in, out}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment