Documentation
¶
Overview ¶
Package utter implements a deep pretty printer for Go data structures to aid data snapshotting.
A quick overview of the additional features utter provides over the built-in printing facilities for Go data types are as follows:
- Pointers are dereferenced and followed
- Circular data structures are detected and annotated
- Byte arrays and slices are dumped in a way similar to the hexdump -C command which includes byte values in hex, and ASCII output
The approach utter allows for dumping Go data structures is less flexible than its parent tool. It has just a:
- Dump style which prints with newlines and customizable indentation
Quick Start ¶
This section demonstrates how to quickly get started with utter. See the sections below for further details on formatting and configuration options.
To dump a variable with full newlines, indentation, type, and pointer information use Dump, Fdump, or Sdump:
utter.Dump(myVar1) utter.Fdump(someWriter, myVar1) str := utter.Sdump(myVar1)
Configuration Options ¶
Configuration of utter is handled by fields in the ConfigState type. For convenience, all of the top-level functions use a global state available via the utter.Config global.
It is also possible to create a ConfigState instance that provides methods equivalent to the top-level functions. This allows concurrent configuration options. See the ConfigState documentation for more details.
The following configuration options are available:
Indent String to use for each indentation level for Dump functions. It is a single space by default. A popular alternative is "\t".
NumericWidth NumericWidth specifies the number of columns to use when dumping a numeric slice or array (including bool). Zero specifies all entries on one line.
StringWidth StringWidth specifies the number of columns to use when dumping a string slice or array. Zero specifies all entries on one line.
BytesWidth Number of byte columns to use when dumping byte slices and arrays.
CommentBytes Specifies whether ASCII comment annotations are attached to byte slice and array dumps.
CommentPointers CommentPointers specifies whether pointer information will be added as comments.
IgnoreUnexported Specifies that unexported fields should be ignored.
ElideType ElideType specifies that type information defined by context should not be printed in a dump.
SortKeys Specifies map keys should be sorted before being printed. Use this to have a more deterministic, diffable output. Note that only native types (bool, int, uint, floats, uintptr and string) are supported with other types sorted according to the reflect.Value.String() output which guarantees display stability. Natural map order is used by default.
Dump Usage ¶
Simply call utter.Dump with a list of variables you want to dump:
utter.Dump(myVar1)
You may also call utter.Fdump if you would prefer to output to an arbitrary io.Writer. For example, to dump to standard error:
utter.Fdump(os.Stderr, myVar1)
A third option is to call utter.Sdump to get the formatted output as a string:
str := utter.Sdump(myVar1)
Sample Dump Output ¶
See the Dump example for details on the setup of the types and variables being shown here.
main.Foo{ unexportedField: &main.Bar{ flag: main.Flag(1), data: uintptr(0), }, ExportedField: map[interface{}]interface{}{ string("one"): bool(true), }, }
Byte (and uint8) arrays and slices are displayed uniquely, similar to the hexdump -C command as shown.
[]uint8{ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, // |........| 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, // |....... | 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, // |!"#$%&'(| 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, // |)*+,-./0| 0x31, 0x32, // |12| }
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var Config = ConfigState{ Indent: " ", NumericWidth: 1, StringWidth: 1, BytesWidth: 16, CommentBytes: true, }
Config is the active configuration of the top-level functions. The configuration can be changed by modifying the contents of utter.Config.
Functions ¶
func Dump ¶
func Dump(a interface{})
Dump displays the passed parameters to standard out with newlines, customizable indentation, and additional debug information such as complete types and all pointer addresses used to indirect to the final value. It provides the following features over the built-in printing facilities provided by the fmt package:
- Pointers are dereferenced and followed
- Circular data structures are detected and annotated
- Byte arrays and slices are dumped in a way similar to the hexdump -C command, which includes byte values in hex, and ASCII output
The configuration options are controlled by an exported package global, utter.Config. See ConfigState for options documentation.
See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to get the formatted result as a string.
Example ¶
This example demonstrates how to use Dump to dump variables to stdout.
package main import ( "fmt" "github.com/kortschak/utter" ) type Flag int const ( flagOne Flag = iota flagTwo ) var flagStrings = map[Flag]string{ flagOne: "flagOne", flagTwo: "flagTwo", } func (f Flag) String() string { if s, ok := flagStrings[f]; ok { return s } return fmt.Sprintf("Unknown flag (%d)", int(f)) } type Bar struct { flag Flag data uintptr } type Foo struct { unexportedField Bar ExportedField map[interface{}]interface{} } func main() { // The following package level declarations are assumed for this example: /* type Flag int const ( flagOne Flag = iota flagTwo ) var flagStrings = map[Flag]string{ flagOne: "flagOne", flagTwo: "flagTwo", } func (f Flag) String() string { if s, ok := flagStrings[f]; ok { return s } return fmt.Sprintf("Unknown flag (%d)", int(f)) } type Bar struct { flag Flag data uintptr } type Foo struct { unexportedField Bar ExportedField map[interface{}]interface{} } */ // Setup some sample data structures for the example. bar := Bar{Flag(flagTwo), uintptr(0)} s1 := Foo{bar, map[interface{}]interface{}{"one": true}} f := Flag(5) b := []byte{ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, } // Dump! utter.Dump([]interface{}{s1, f, b}) }
Output: []interface{}{ utter_test.Foo{ unexportedField: utter_test.Bar{ flag: utter_test.Flag(1), data: uintptr(0), }, ExportedField: map[interface{}]interface{}{ string("one"): bool(true), }, }, utter_test.Flag(5), []uint8{ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, // |............... | 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, // |!"#$%&'()*+,-./0| 0x31, 0x32, /* */ // |12| }, }
Types ¶
type ConfigState ¶
type ConfigState struct { // Indent specifies the string to use for each indentation level. The // global config instance that all top-level functions use set this to a // single space by default. If you would like more indentation, you might // set this to a tab with "\t" or perhaps two spaces with " ". Indent string // NumericWidth specifies the number of columns to use when dumping // a numeric slice or array (including bool). Zero specifies all entries // on one line. NumericWidth int // StringWidth specifies the number of columns to use when dumping // a string slice or array. Zero specifies all entries on one line. StringWidth int // Quoting specifies the quoting strategy to use when printing strings. Quoting Quoting // BytesWidth specifies the number of byte columns to use when dumping a // byte slice or array. If this is not set or negative, a value of 16 // is used. BytesWidth int // CommentBytes specifies whether byte slice or array dumps have ASCII // comment annotations. CommentBytes bool // AddressBytes specifies whether byte slice or array dumps have index // annotations. AddressBytes bool // CommentPointers specifies whether pointer information will be added // as comments. CommentPointers bool // IgnoreUnexported specifies that unexported struct fields should be // ignored during a dump. IgnoreUnexported bool // OmitZero specifies that zero values should not be printed in a dump. OmitZero bool // LocalPackage specifies a package selector to trim from type information. LocalPackage string // ElideType specifies that type information defined by context should // not be printed in a dump. ElideType bool // SortKeys specifies map keys should be sorted before being printed. Use // this to have a more deterministic, diffable output. Note that only // native types (bool, int, uint, floats, uintptr and string) are supported // with other types sorted according to the reflect.Value.String() output // which guarantees display stability. SortKeys bool }
ConfigState houses the configuration options used by utter to format and display values. There is a global instance, Config, that is used to control all top-level Formatter and Dump functionality. Each ConfigState instance provides methods equivalent to the top-level functions.
The zero value for ConfigState provides no indentation. You would typically want to set it to a space or a tab.
Alternatively, you can use NewDefaultConfig to get a ConfigState instance with default settings. See the documentation of NewDefaultConfig for default values.
Example ¶
This example demonstrates how to use a ConfigState.
package main import ( "github.com/kortschak/utter" ) func main() { // Modify the indent level of the ConfigState only. The global // configuration is not modified. scs := utter.ConfigState{Indent: "\t"} // Output using the ConfigState instance. v := map[string]int{"one": 1} scs.Dump(v) }
Output: map[string]int{ string("one"): int(1), }
func NewDefaultConfig ¶
func NewDefaultConfig() *ConfigState
NewDefaultConfig returns a ConfigState with the following default settings.
Indent: " " NumericWidth: 1, StringWidth: 1, BytesWidth: 16 CommentBytes: true CommentPointers: false IgnoreUnexported: false ElideType: false SortKeys: false
func (*ConfigState) Dump ¶
func (c *ConfigState) Dump(a interface{})
Dump displays the passed parameters to standard out with newlines, customizable indentation, and additional debug information such as complete types and all pointer addresses used to indirect to the final value. It provides the following features over the built-in printing facilities provided by the fmt package:
- Pointers are dereferenced and followed
- Circular data structures are detected and handled properly
- Byte arrays and slices are dumped in a way similar to the hexdump -C command which includes byte values in hex, and ASCII output
The configuration options are controlled by modifying the public members of c. See ConfigState for options documentation.
See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to get the formatted result as a string.
Example ¶
This example demonstrates how to use ConfigState.Dump to dump variables to stdout
package main import ( "fmt" "github.com/kortschak/utter" ) type Flag int const ( flagOne Flag = iota flagTwo ) var flagStrings = map[Flag]string{ flagOne: "flagOne", flagTwo: "flagTwo", } func (f Flag) String() string { if s, ok := flagStrings[f]; ok { return s } return fmt.Sprintf("Unknown flag (%d)", int(f)) } type Bar struct { flag Flag data uintptr } type Foo struct { unexportedField Bar ExportedField map[interface{}]interface{} } func main() { // See the top-level Dump example for details on the types used in this // example. // Create two ConfigState instances with different indentation. scs := utter.ConfigState{Indent: "\t"} scs2 := utter.ConfigState{Indent: " "} // Setup some sample data structures for the example. bar := Bar{Flag(flagTwo), uintptr(0)} s1 := Foo{bar, map[interface{}]interface{}{"one": true}} // Dump using the ConfigState instances. scs.Dump(s1) scs2.Dump(s1) }
Output: utter_test.Foo{ unexportedField: utter_test.Bar{ flag: utter_test.Flag(1), data: uintptr(0), }, ExportedField: map[interface{}]interface{}{ string("one"): bool(true), }, } utter_test.Foo{ unexportedField: utter_test.Bar{ flag: utter_test.Flag(1), data: uintptr(0), }, ExportedField: map[interface{}]interface{}{ string("one"): bool(true), }, }
func (*ConfigState) Fdump ¶
func (c *ConfigState) Fdump(w io.Writer, a interface{})
Fdump formats and displays the passed arguments to io.Writer w. It formats exactly the same as Dump.
func (*ConfigState) Sdump ¶
func (c *ConfigState) Sdump(a interface{}) string
Sdump returns a string with the passed arguments formatted exactly the same as Dump.
type Quoting ¶ added in v1.5.0
type Quoting uint
Quoting describes string quoting strategies.
The numerical values of quoting constants are not guaranteed to be stable.
const ( // Quote strings with double quotes. DoubleQuote Quoting = 0 // AvoidEscapes quotes strings using backquotes to avoid escape // sequences if possible, otherwise double quotes are used. AvoidEscapes Quoting = 1 << iota // Backquote always quotes strings using backquotes where possible // within the string. For sections of strings that can not be // backquoted, additional double quote syntax is used. Backquote // Force is a modifier of AvoidEscapes that adds additional double // quote syntax to represent parts that cannot be backquoted. Force )