dave / forky

A tool to automate forking and modifying codebases
8 stars 1 forks source link

Inject package session to methods without breaking interfaces #2

Open dave opened 6 years ago

dave commented 6 years ago

We can't rely on injecting the PackageSession into methods because we break interfaces.

Consider:

var i int

type T struct{}

func (T) Write(data []byte) (int, error) {
    i++
    return 0, nil
}

func foo() {
    t := T{}
    fmt.Fprint(t, "foo")
}

We need access to the PackageSession inside the Write method, but we can't add it to the signature without no longer satisfying the io.Writer interface. I believe only solution is to add the PackageSession to T itself, so the code would become:

type T struct{
    psess *PacckageSession
}

func (t T) Write(data []byte) (int, error) {
    t.psess.i++
    return 0, nil
}

func (psess *PackageSession)foo() {
    t := T{
        psess: psess,
    }
    fmt.Fprint(t, "foo")
}

// in package-session.go:

type PackageSession struct {
    i int
}
...

This is complex enough if all types were structs. When you consider all non-struct types would need to be converted to structs is becomes a very hard problem - e.g.:

type T int

//...

t := T(1)

fmt.Println(t)

need to become:

type T struct{
    psess *PackageSession
    Value int
}

//...

t := T{
    psess: psess,
    Value: 1,
}

fmt.Println(t.Value)