sharedFlag := "init-value"
fooFs := flag.NewFlagSet("foo", flag.ContinueOnError)
barFs := flag.NewFlagSet("bar", flag.ContinueOnError)
fooFs.StringVar(&sharedFlag, "baz", "foo-default", "testing")
barFs.StringVar(&sharedFlag, "baz", "bar-default", "testing")
_ = fooFs.Parse([]string{""}) // no error
fmt.Println(*sharedFlag) // bar-default, instead of foo-default
>
Haha! This is a bug (?) with stdlib flag.FlagSet.
> The default value provided to e.g. fs.StringVar isn't kept as
metadata associated with the flag in the corresponding flagset, but is
rather assigned to the associated variable. And that assignment happens
at declaration time, when you call fs.StringVar, and not when you call
fs.Parse. So the default value you see in any flag set will be the
default value provided to whichever StringVar declaration happens to
occur last — in your test, it's this one.
> This sucks.
> I think the only fix here would be, somehow, avoiding assigning a
default value in the declaration, and populating it later. Or defining a
separate e.g. DeferredFlagVar type that encapsulated this behavior? I
don't know offhand what's best. Ugh.
I never contributed to the go repo yet, so I prefer to ask here your opinion about this strange behavior, what you suggest in term of fix that does not require to touch the stdlib, and if you think that I need to issue a bug on the go repo and try to contribute a fix?
Thank you,