diff --git a/spew/config.go b/spew/config.go index 2e3d22f..580e005 100644 --- a/spew/config.go +++ b/spew/config.go @@ -98,6 +98,10 @@ type ConfigState struct { // be spewed to strings and sorted by those strings. This is only // considered if SortKeys is true. SpewKeys bool + + // DisableFunctionTypePointerAddresses specifies whether to disable the printing of + // function types pointer addresses. This is useful when diffing data structures in tests. + DisableFunctionTypePointerAddresses bool } // Config is the active configuration of the top-level functions. diff --git a/spew/dump.go b/spew/dump.go index f78d89f..ea42269 100644 --- a/spew/dump.go +++ b/spew/dump.go @@ -433,7 +433,14 @@ func (d *dumpState) dump(v reflect.Value) { case reflect.Uintptr: printHexPtr(d.w, uintptr(v.Uint())) - case reflect.UnsafePointer, reflect.Chan, reflect.Func: + case reflect.Func: + if d.cs.DisableFunctionTypePointerAddresses { + fmt.Fprintf(d.w, "%v", v.String()) + } else { + printHexPtr(d.w, v.Pointer()) + } + + case reflect.UnsafePointer, reflect.Chan: printHexPtr(d.w, v.Pointer()) // There were not any other types at the time this code was written, but diff --git a/spew/spew_test.go b/spew/spew_test.go index b70466c..2397a3e 100644 --- a/spew/spew_test.go +++ b/spew/spew_test.go @@ -123,6 +123,10 @@ func redirStdout(f func()) ([]byte, error) { return ioutil.ReadFile(fileName) } +func someFunc(value string) string { + return value +} + func initSpewTests() { // Config states with various settings. scsDefault := spew.NewDefaultConfig() @@ -131,6 +135,7 @@ func initSpewTests() { scsMaxDepth := &spew.ConfigState{Indent: " ", MaxDepth: 1} scsContinue := &spew.ConfigState{Indent: " ", ContinueOnMethod: true} scsNoPtrAddr := &spew.ConfigState{DisablePointerAddresses: true} + scsNoFuncPtrAddr := &spew.ConfigState{DisablePointerAddresses: true, DisableFunctionTypePointerAddresses: true} scsNoCap := &spew.ConfigState{DisableCapacities: true} // Variables for tests on types which implement Stringer interface with and @@ -138,10 +143,18 @@ func initSpewTests() { ts := stringer("test") tps := pstringer("test") + type someFuncType func(string) string + type ptrTester struct { s *struct{} } + + type ptrFuncTester struct { + funcField someFuncType + } + tptr := &ptrTester{s: &struct{}{}} + tptrFunc := &ptrFuncTester{funcField: someFunc} // depthTester is used to test max depth handling for structs, array, slices // and maps. @@ -201,6 +214,9 @@ func initSpewTests() { "(error: 10) 10\n"}, {scsNoPtrAddr, fCSFprint, "", tptr, "<*>{<*>{}}"}, {scsNoPtrAddr, fCSSdump, "", tptr, "(*spew_test.ptrTester)({\ns: (*struct {})({\n})\n})\n"}, + + {scsNoFuncPtrAddr, fCSSdump, "", tptrFunc, "(*spew_test.ptrFuncTester)({\nfuncField: (spew_test.someFuncType) \n})\n"}, + {scsNoCap, fCSSdump, "", make([]string, 0, 10), "([]string) {\n}\n"}, {scsNoCap, fCSSdump, "", make([]string, 1, 10), "([]string) (len=1) {\n(string) \"\"\n}\n"}, }