remove: log parser from interfaces

This commit is contained in:
Inanc Gumus
2019-08-31 17:23:50 +03:00
parent 81bd060e1b
commit 1ee44f1f9d
7 changed files with 0 additions and 239 deletions

View File

@ -1,36 +0,0 @@
# Problem
## All these functions operate on a *parser value:
+ `main.go`:
+ `summarize(*p parser)`
+ `parser.go`:
+ `func parse(p *parser, line string) (r result)`
+ `func update(p *parser, r result)`
+ `func err(p *parser) error`
## What is an object in Go?
+ Object = A value of a type : `&parser{}` is an object.
+ `type parser struct` is the definition (class/blueprint) of the object.
### Methods are behaviors of objects:
+ Parser needs to parse, update (analyse) the parsings, and report an error if any.
+ Parser also needs to summarize the results.
+ So, all these functions belong to a parser object.
# Solution
+ Attach the functions to the parser using methods.
+ Methods are the behavior of the parser.
+ Keep the methods that belong to a single type in the same file.
1. Move the `summarize` into `parser.go`.
2. `parser.go`: Use methods.
3. `main()` : Use methods of the `parser`.
# Convince
+ `p.` shows the fields and methods belong to the `parser`.
+ `p.` selects a method from the method set of the `parser`.
+ `p.method` sends the `p` as the first parameter to the method.
+ `p` is the receiver: `*pointer`. It's a pointer receiver.
+ Receiver is copied to the method.

View File

@ -1,16 +0,0 @@
learngoprogramming.com 10
learngoprogramming.com 15
learngoprogramming.com 10
learngoprogramming.com 20
learngoprogramming.com 5
golang.org 40
golang.org 20
golang.org 45
golang.org 15
blog.golang.org 60
blog.golang.org 30
blog.golang.org 20
blog.golang.org 65
blog.golang.org 15
inanc.io 30
inanc.io 70

View File

@ -1,16 +0,0 @@
learngoprogramming.com 10
learngoprogramming.com 15
learngoprogramming.com 10
learngoprogramming.com 20
learngoprogramming.com
golang.org 40
golang.org 20
golang.org 45
golang.org 15
blog.golang.org 60
blog.golang.org 30
blog.golang.org 20
blog.golang.org 65
blog.golang.org 15
inanc.io 30
inanc.io 70

View File

@ -1,16 +0,0 @@
learngoprogramming.com 10
learngoprogramming.com 15
learngoprogramming.com 10
learngoprogramming.com 20
learngoprogramming.com 5
golang.org 40
golang.org 20
golang.org -50
golang.org 15
blog.golang.org 60
blog.golang.org 30
blog.golang.org 20
blog.golang.org 65
blog.golang.org 15
inanc.io 30
inanc.io 70

View File

@ -1,16 +0,0 @@
learngoprogramming.com 10
learngoprogramming.com 15
learngoprogramming.com 10
learngoprogramming.com 20
learngoprogramming.com 5
golang.org FORTY
golang.org 20
golang.org 45
golang.org 15
blog.golang.org 60
blog.golang.org 30
blog.golang.org 20
blog.golang.org 65
blog.golang.org 15
inanc.io 30
inanc.io 70

View File

@ -1,39 +0,0 @@
// For more tutorials: https://blog.learngoprogramming.com
//
// Copyright © 2018 Inanc Gumus
// Learn Go Programming Course
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
//
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
p := newParser()
fmt.Printf("%T\n", (*parser).parse)
return
in := bufio.NewScanner(os.Stdin)
for in.Scan() {
parsed := p.parse(in.Text())
p.update(parsed)
}
p.summarize()
dumpErrs([]error{in.Err(), p.err()})
}
// dumpErrs together to simplify multiple error handling
func dumpErrs(errs []error) {
for _, err := range errs {
if err != nil {
fmt.Println("> Err:", err)
}
}
}

View File

@ -1,100 +0,0 @@
// For more tutorials: https://blog.learngoprogramming.com
//
// Copyright © 2018 Inanc Gumus
// Learn Go Programming Course
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
//
package main
import (
"fmt"
"sort"
"strconv"
"strings"
)
// result stores details about a log line
type result struct {
domain string
visits int
// add more metrics when needed
}
// parser keep tracks of the parsing
type parser struct {
sum map[string]result // metrics per domain
domains []string // unique domain names
total int // total visits for all domains
lines int // number of parsed lines (for the error messages)
lerr error // the last error occurred
}
// newParser creates and returns a new parser
func newParser() *parser {
return &parser{sum: make(map[string]result)}
}
// parse result from a log line
func (p *parser) parse(line string) (r result) {
if p.lerr != nil {
return
}
p.lines++
fields := strings.Fields(line)
if len(fields) != 2 {
p.lerr = fmt.Errorf("wrong input: %v (line #%d)", fields, p.lines)
return
}
var err error
r.domain = fields[0]
r.visits, err = strconv.Atoi(fields[1])
if r.visits < 0 || err != nil {
p.lerr = fmt.Errorf("wrong input: %q (line #%d)", fields[1], p.lines)
}
return
}
// update the parsing results
func (p *parser) update(r result) {
if p.lerr != nil {
return
}
// collect unique domains for easy access to sum map
if _, ok := p.sum[r.domain]; !ok {
p.domains = append(p.domains, r.domain)
}
// keep track of total visits
p.total += r.visits
// group the log lines by domain
p.sum[r.domain] = result{
domain: r.domain,
visits: r.visits + p.sum[r.domain].visits,
}
}
// summarize the parsing results
func (p *parser) summarize() {
sort.Strings(p.domains)
fmt.Printf("%-30s %10s\n", "DOMAIN", "VISITS")
fmt.Println(strings.Repeat("-", 45))
for _, domain := range p.domains {
fmt.Printf("%-30s %10d\n", domain, p.sum[domain].visits)
}
fmt.Printf("\n%-30s %10d\n", "TOTAL", p.total)
}
// err returns the last error encountered
func (p *parser) err() error {
return p.lerr
}