Skip to content

Instantly share code, notes, and snippets.

@bprosnitz
Last active October 2, 2015 21:54
Show Gist options
  • Save bprosnitz/76feef68a11b312ac4bc to your computer and use it in GitHub Desktop.
Save bprosnitz/76feef68a11b312ac4bc to your computer and use it in GitHub Desktop.
dump objects / deep print
func dump(seen map[reflect.Value]bool, rv reflect.Value) string {
if rv.Kind() == reflect.Invalid {
return "nil"
}
if _, ok := seen[rv]; ok {
return "SEEN[" + rv.Type().Name() + "]"
}
seen[rv] = true
method := rv.MethodByName("String")
if method.IsValid() {
return "STRFORM[" + method.Call([]reflect.Value{})[0].Interface().(string) + "]"
}
switch rv.Kind() {
case reflect.Bool:
return strconv.FormatBool(rv.Bool())
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return strconv.FormatInt(rv.Int(), 10)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return strconv.FormatUint(rv.Uint(), 10)
case reflect.Float32, reflect.Float64:
return fmt.Sprintf("%f", rv.Float())
case reflect.Complex64, reflect.Complex128:
return fmt.Sprintf("%f+%fi", real(rv.Complex()), imag(rv.Complex()))
case reflect.Array, reflect.Slice:
var len int
var str string
if rv.Kind() == reflect.Array {
len = rv.Type().Len()
str = fmt.Sprintf("[%d]", len)
} else {
len = rv.Len()
str = "[]"
}
str += rv.Type().Elem().String()
str += "{"
for i := 0; i < len; i++ {
if i > 0 {
str += ", "
}
str += dump(seen, rv.Index(i))
}
str += "}"
return str
case reflect.Map:
str := rv.Type().String()
str += "{"
for index, key := range rv.MapKeys() {
if index > 0 {
str += ", "
}
str += dump(seen, key)
str += ": "
str += dump(seen, rv.MapIndex(reflect.ValueOf(index)))
}
str += "}"
return str
case reflect.Struct:
str := rv.Type().String()
str += "{"
for i := 0; i < rv.NumField(); i++ {
if i > 0 {
str += ", "
}
str += rv.Type().Field(i).Name
str += ": "
str += dump(seen, rv.Field(i))
}
str += "}"
return str
case reflect.String:
return strconv.Quote(rv.String())
case reflect.Interface:
return dump(seen, rv.Elem())
case reflect.Ptr:
return "&" + dump(seen, rv.Elem())
default:
panic(fmt.Sprintf("kind %v not currently supported", rv.Kind()))
}
}
func Debugf(format string, args ...interface{}) {
parts := strings.Split(format, "%w")
if len(parts) != len(args)+1 {
panic("number of arguments does not match format string")
}
str := ""
for i := 0; i < len(args); i++ {
str += parts[i]
str += parts[i]
str += dump(make(map[reflect.Value]bool), reflect.ValueOf(args[i]))
}
str += parts[len(parts)-1]
fmt.Printf("%s", str)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment