These are packaged in a tiny git.lsub.org/go.git/dbg.go package.
First, this is a well known idiom to trace function calls, only that I modified it to report also the file and line number in a convenient way.
It is used as in this excerpt
func ReadMsgsFrom(r io.Reader, c chan<- []byte) (int64, error) {
defer dbg.Trace(dbg.Call("ReadMsgsFrom"))
...
And produces messages like these ones:
bgn ReadMsgsFrom nchan.go:116
end ReadMsgsFrom nchan.go:116
The functions are like follows:
// For use as in defer dbg.Trace(Call("funcname"))
func Trace(s string) {
fmt.Printf("end %s\n", s)
}
// For use as in defer dbg.Trace(Call("funcname"))
func Call(s string) string {
if _, file, lno, ok := runtime.Caller(1); ok {
rel, _ := filepath.Rel(cwd, file)
s = fmt.Sprintf("%s %s:%d", s, rel, lno)
}
fmt.Printf("bgn %s\n", s)
return s
}
The second tool is a couple of functions that enable prints only if a flag is set or if another function says so. They are used like in
var Printf = dbg.FuncPrintf(os.Stdout, testing.Verbose)
func TestChanSend(t *testing.T) {
...
Printf("receiver %v\n", msg)
}
The variable name should reflect that it is a conditional print, but in this case I took the code from a testing file, which prints only if verbose is set during the test. The idea is that you can declare as many print functions (variables) you want to print conditionally when certain flags are enabled.
This is the code from the debug package
type PrintFunc func(fmts string, arg ...interface{}) (int, error)
/*
Return a function that calls fmt.Printf only if fn returns true.
To be used like in
var Printf = verb.PrintfFunc(testing.Verbose)
...
Printf(...)
*/
func FuncPrintf(w io.Writer, fn func()bool) PrintFunc {
return func(fmts string, arg ...interface{}) (int, error) {
if fn() {
return fmt.Fprintf(w, fmts, arg...)
}
return 0, nil
}
}
The function returns a function that prints, only that it prints only if the function given as an argument says so. Thus, when you declare your print function variable you can set the condition to trigger the print and the writer the print should use. The rest of the code is relieved from the burden of testing the condition or typing more to use a particular output stream.
There is a similar function (returning a conditional printing function) that takes a pointer to a boolean flag instead of a function, for those cases when checking a flag suffice.