Created
January 9, 2015 16:11
-
-
Save jakecoffman/a307d6dd754f7612f2de to your computer and use it in GitHub Desktop.
Unix-y pipelines in Go (functional programming)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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