substack/node-optimist — pull request #119 by Chevex (2013-11-06 18:49:55+00:00)
Title: Added a `resetOptions` function to the API for instances where you need ...

...to clear defined options so they can be redefined.

I wrote a node module called [shotgun](http://github.com/Chevex/shotgun) which is a custom shell for which "command modules" (node modules that adhere to a spec with what they define on `exports`) can be written. These command modules define various options they understand. One of the defined option properties is `type` which can be set to `"boolean"`.

This is so that when shotgun is parsing the defined options it can inform optimist that this option should be treated as a boolean, otherwise optimist will suck in the next value on the command line when the user did not intend it to. This works great when executing one command module that defines a boolean option. However, if I then invoke a second command module that defines an option with the same name but **not** a boolean, optimist will still try to parse it as a boolean.

This is when I discovered that optimist has no way of clearing defined options. Even the options object itself is kept private so you can't even manually remove the defined option. I got this functionality to work with a workaround:

// Remove optimist from the module cache so it won't remember options we defined during last execution.
for (var key in require.cache)
if (key.match(/optimist\\index\.js$/))
delete require.cache[key];

var shell = this,
optimist = require('optimist'); // Get fresh reference to optimist with every execution.

// Todo: Modify optimist with a resetOptions function. When the pull request is accepted put the require back at the top and remove the code to invalidate the cache. Then make a call to the new optimist function instead.

With the change in this pull request I can now remove all that code and simply call `resetOptions()`.

optimist.resetOptions();

I thought about just modifying optimist so that defining an option overrides the previously defined option. I still might do that too, but that wouldn't solve my problem because my module does not require the user to define any options, but the user can still pass them in if they wish. This means if commandModule-A defines option "temp" as a boolean, then commandModule-B who has no options defined would still receive "temp" as a boolean from optimist if it was supplied.

I hope that clearly explains why I think this function is a good addition to the library. Let me know if there is any confusion.