New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: fmt: use "%##v" "%++v" to format a value with indented-multi-lines style string #23026

Closed
vipally opened this Issue Dec 7, 2017 · 6 comments

Comments

Projects
None yet
6 participants
@vipally
Copy link

vipally commented Dec 7, 2017

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

go 1.9

Does this issue reproduce with the latest release?

yes

Current custom go data printing style "%#v" show all data in a single line, which is not easy to read, especiall in a debugging process.
"%#v":
fmt_test.Z{G:fmt_test.Y{D:fmt_test.X{A:123, B:""b" = 1"}, E:[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, F:[2]string{"aaa", "bbb"}}, H:"zzz", I:[]string{"c:\x\y\z", "d:\a\b\c"}, J:map[string]int{"abc":456}}

I have made a patch to use "%##v" "%++v" to format a value with indented-multi-lines style string to extends "%#v" "%+v".
I expect this feature can be accepted by go team, and it will be my pleasure to contribute this patch to go repository.

Branch
Example

here is the expected example

func ExamplePrintf_flagV() {
	type X struct {
		A int
		B string
	}
	type Y struct {
		D X
		E []int
		F [2]string
	}
	type Z struct {
		G Y
		H string
		I []string
		J map[string]int
	}
	var z = Z{
		G: Y{
			D: X{
				A: 123,
				B: `"b" = 1`,
			},
			E: []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12},
			F: [2]string{
				`aaa`,
				`bbb`,
			},
		},
		H: `zzz`,
		I: []string{
			`c:\x\y\z`,
			`d:\a\b\c`,
		},
		J: map[string]int{
			`abc`: 456,
		},
	}
	fmt.Printf("-------\n\"%%v\":\n%v\n", z)
	fmt.Printf("-------\n\"%%#v\":\n%#v\n", z)
	fmt.Printf("-------\n\"%%##\"v:\n%##v\n", z)
	fmt.Printf("-------\n\"%%+v\":\n%+v\n", z)
	fmt.Printf("-------\n\"%%++v\":\n%++v\n", z)

	// Output:
	// -------
	// "%v":
	// {{{123 "b" = 1} [1 2 3 4 5 6 7 8 9 10 11 12] [aaa bbb]} zzz [c:\x\y\z d:\a\b\c] map[abc:456]}
	// -------
	// "%#v":
	// fmt_test.Z{G:fmt_test.Y{D:fmt_test.X{A:123, B:"\"b\" = 1"}, E:[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, F:[2]string{"aaa", "bbb"}}, H:"zzz", I:[]string{"c:\\x\\y\\z", "d:\\a\\b\\c"}, J:map[string]int{"abc":456}}
	// -------
	// "%##"v:
	// fmt_test.Z{
	//     G: fmt_test.Y{
	//         D: fmt_test.X{
	//             A: 123,
	//             B: `"b" = 1`,
	//         },
	//         E: []int{
	//             1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
	//             11, 12,
	//         },
	//         F: [2]string{
	//             `aaa`,
	//             `bbb`,
	//         },
	//     },
	//     H: `zzz`,
	//     I: []string{
	//         `c:\x\y\z`,
	//         `d:\a\b\c`,
	//     },
	//     J: map[string]int{
	//         `abc`: 456,
	//     },
	// }
	// -------
	// "%+v":
	// {G:{D:{A:123 B:"b" = 1} E:[1 2 3 4 5 6 7 8 9 10 11 12] F:[aaa bbb]} H:zzz I:[c:\x\y\z d:\a\b\c] J:map[abc:456]}
	// -------
	// "%++v":
	// {
	//     G: {
	//         D: {
	//             A: 123
	//             B: "b" = 1
	//         }
	//         E: [
	//             1 2 3 4 5 6 7 8 9 10
	//             11 12
	//         ]
	//         F: [
	//             aaa
	//             bbb
	//         ]
	//     }
	//     H: zzz
	//     I: [
	//         c:\x\y\z
	//         d:\a\b\c
	//     ]
	//     J: map[
	//         abc: 456
	//     ]
	// }
}

Branch
Example

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

ianlancetaylor commented Dec 7, 2017

Personally I think this is more suitable for an external packages, such as https://godoc.org/github.com/kr/pretty.

@ianlancetaylor

This comment has been minimized.

Copy link
Contributor

ianlancetaylor commented Dec 7, 2017

Thanks for writing it up, though.

@martisch

This comment has been minimized.

Copy link
Member

martisch commented Dec 8, 2017

I would favor this functionallity having its own package instead of making the fmt flag logic and functionality more complex too.

I would also recommend to avoid giving different meaning to multiple occurences of format flags but to use a new one instead to signify pretty printing using multiple lines.

@vipally

This comment has been minimized.

Copy link
Author

vipally commented Dec 8, 2017

Printing go value for debugging becomes gopher's everyday life, I don't think it's a good idea to make it a third-party package.

Put a new flag to to signify pretty printing is a good idea.
eg '@' (maybe looks like glasses, yet)

@robpike

This comment has been minimized.

Copy link
Contributor

robpike commented Jan 13, 2018

I too agree it should be outside. The fmt package is complex enough already, and the features you ask for will complicate it a great deal.

I will make this a proposal so it gets a full review.

@robpike robpike changed the title fmt: use "%##v" "%++v" to format a value with indented-multi-lines style string proposal: fmt: use "%##v" "%++v" to format a value with indented-multi-lines style string Jan 13, 2018

@gopherbot gopherbot added the Proposal label Jan 13, 2018

@robpike robpike removed the NeedsDecision label Jan 13, 2018

@robpike robpike removed this from the Unplanned milestone Jan 13, 2018

@robpike robpike removed their assignment Jan 13, 2018

@rsc

This comment has been minimized.

Copy link
Contributor

rsc commented Jan 22, 2018

The correct link for the code appears to be https://github.com/vipally/go/tree/ally_master/src/fmt, which uses %@#v and %@+v, I assume because the fmt.Formatter API cannot express two of a given flag.

Everyone who has commented has said that this can be best done as a separate package, or multiple separate packages if different uses need different rules. That seems right to me too.

Closing after discussion with proposal-review (everyone agreed).

@rsc rsc closed this Jan 22, 2018

@golang golang locked and limited conversation to collaborators Jan 22, 2019

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.