Flag package unexpected behaviour....

108 views
Skip to first unread message

Ken MacDonald

unread,
Feb 27, 2015, 11:05:38 AM2/27/15
to golan...@googlegroups.com
I've been using the "flag" package to parse a command line argument, "-cfg file.conf" to get the name of a config file.

I used:

flag.StringVar(&cfgFile, "cfg", "file.conf", "-cfg file.conf")

followed by:

gcfg.ReadFileInto(&Cfg, cfgFile)   // Cfg is a struct...

which reads the file named in the variable cfgFile just peachy. As long as that file name is "file.conf".

Note that I had forgotten to call flag.Parse().... but the value of the variable "cfgFile" is set to my default value anyway. The doc for the flag package says that
the flag variables are not usable until after flag.Parse() is called, which - to me - indicates that "cfgFile" should have been empty. This seems like a bug in the flag package. The flag variables defined should really not have values until flag.Parse() runs - assigning the defaults at the time the flags are first defined made it difficult to notice that I had an error in my logic until the program moved to another platform and we tried to run:

./myprogram -cfg someotherfile.conf

which immediately croaked with "can't open file.conf".

Since the doc says that flag.Parse() is needed to set the flag values, it would be great if it actually worked that way.
Ken

Egon

unread,
Feb 27, 2015, 11:22:58 AM2/27/15
to golan...@googlegroups.com


On Friday, 27 February 2015 18:05:38 UTC+2, Ken MacDonald wrote:
I've been using the "flag" package to parse a command line argument, "-cfg file.conf" to get the name of a config file.

I used:

flag.StringVar(&cfgFile, "cfg", "file.conf", "-cfg file.conf")

followed by:

gcfg.ReadFileInto(&Cfg, cfgFile)   // Cfg is a struct...

which reads the file named in the variable cfgFile just peachy. As long as that file name is "file.conf".

Note that I had forgotten to call flag.Parse().... but the value of the variable "cfgFile" is set to my default value anyway. The doc for the flag package says that
the flag variables are not usable until after flag.Parse() is called,

I can't find that part in the documentation where it says that.
 
which - to me - indicates that "cfgFile" should have been empty. This seems like a bug in the flag package. The flag variables defined should really not have values until flag.Parse() runs - assigning the defaults at the time the flags are first defined made it difficult to notice that I had an error in my logic until the program moved to another platform and we tried to run:

./myprogram -cfg someotherfile.conf

which immediately croaked with "can't open file.conf".
 
Since the doc says that flag.Parse() is needed to set the flag values, it would be great if it actually worked that way.
Ken

Search for the part

For such flags, the default value is just the initial value of the variable.

Ken MacDonald

unread,
Feb 27, 2015, 11:29:45 AM2/27/15
to Egon, golang-nuts
From the doc:

func Parse

func Parse()
Parse parses the command-line flags from os.Args[1:]. Must be called after all flags are defined and before flags are accessed by the program.

But, it doesn't actually work this way - as documented - as my program was able to "access the flag" before calling Parse(). And it had a valid (default) value, which led to having a somewhat-subtle bug.
Ken

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Rob Pike

unread,
Feb 27, 2015, 11:32:42 AM2/27/15
to Ken MacDonald, Egon, golang-nuts
The flag will be initialized when the package declaring it has its initialization run, which is before main starts.

This is expected and standard Go behavior, no different than from any other variable.

You need to call Parse if you want to modify the default value by scanning the command line, of course. There really should be nothing surprising or in need of extra documentation here.

-rob

Egon

unread,
Feb 27, 2015, 11:35:27 AM2/27/15
to golan...@googlegroups.com, egon...@gmail.com


On Friday, 27 February 2015 18:29:45 UTC+2, Ken MacDonald wrote:
From the doc:

func Parse

func Parse()
Parse parses the command-line flags from os.Args[1:]. Must be called after all flags are defined and before flags are accessed by the program.

It simply says it must be called, but it doesn't say what their value is or what happens when you access them. Basically, that behavior is simply undefined.
Reply all
Reply to author
Forward
0 new messages