Skip to content
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

If an argument is missing, it's value is "nil" (a string), not nil (the real nil). #22

Open
moigagoo opened this issue Oct 4, 2016 · 10 comments

Comments

@moigagoo
Copy link

@moigagoo moigagoo commented Oct 4, 2016

I have an isNil check in my code that used to work with the older version. Now it breaks because isNil is false due to the value being "nil," not nil.

@oprypin

This comment has been minimized.

Copy link
Member

@oprypin oprypin commented Oct 4, 2016

Please clarify (give an example that fails).

@moigagoo

This comment has been minimized.

Copy link
Author

@moigagoo moigagoo commented Oct 4, 2016

Consider the following simple example:

import docopt

const doc = """
Foo.

Usage:
  doco do [--param=<some-param>]
  doco (-h | --help)
  doco --version

Options:
  -h --help                         Show this screen.
  -v --version                      Show version.
  -p --param=<some-param>           Some param without default value.
"""

let args = docopt(doc, version = "0.1.0")

if args["do"]:
  let param = $args["--param"] # expected to be nil if not passed

  echo param.isNil
  echo param == "nil"

Compile and run it:

$ doco do
false
true

$ doco do -p foo
false
false

As you can see, if --param is not provided, its value is "nil" the string, not nil the default string value.

@oprypin

This comment has been minimized.

Copy link
Member

@oprypin oprypin commented Oct 4, 2016

You are converting the value to string using $ and then wondering why it's a string?

@oprypin oprypin closed this Oct 4, 2016
@moigagoo

This comment has been minimized.

Copy link
Author

@moigagoo moigagoo commented Oct 4, 2016

Terribly sorry. What a stupid mistake...

@moigagoo

This comment has been minimized.

Copy link
Author

@moigagoo moigagoo commented Oct 4, 2016

@BlaXpirit Still, it's a bit weird that $ applied to vkNone value produces a non-empty string, don't you think? nil is a valid value for string type, and it feels like a good reflection of vkNone.

I'm asking for two reasons:

  • it used to work this way; isNil did return true in this situation
  • in order to check if a param was passed, I have to check if its kind is vkNone, which means I have to import docopt whenever I need to perform such a check.
@oprypin

This comment has been minimized.

Copy link
Member

@oprypin oprypin commented Oct 4, 2016

I am sure that applying $ to a Value never returned nil and I don't think this is a good idea, because generally $ always returns a string.

Nim's shenanigans with imports and availability of methods is a whole another topic...

@oprypin

This comment has been minimized.

Copy link
Member

@oprypin oprypin commented Oct 4, 2016

I'm sorry, it seems like I am incorrect, and $nil returns actual nil in Nim.

@oprypin oprypin reopened this Oct 4, 2016
@moigagoo

This comment has been minimized.

Copy link
Author

@moigagoo moigagoo commented Oct 4, 2016

@BlaXpirit So, do you too think that $ applied to vkNone should return nil? IMHO it makes perfect sense.

@moigagoo

This comment has been minimized.

Copy link
Author

@moigagoo moigagoo commented Oct 4, 2016

@BlaXpirit

generally $ always returns a string.

There's no contradiction with my proposal. nil is a string.

@vsajip

This comment has been minimized.

Copy link

@vsajip vsajip commented Jan 11, 2017

Here's another example of what looks like a problem. The following script:

let doc = """
A test program
Usage:
  test [CONFIG]

Options:
  CONFIG        Path to configuration file
"""
import strutils
import docopt

let args = docopt(doc, version = "Test 0.1.0")
echo args
let no_config = ($args["CONFIG"]).isNil
echo no_config

Compiles without errors on Nim 0.16.0 (Ubuntu 16.04, x86_64).

When the compiled program is run with no arguments:

$ ./test
{CONFIG: nil}
false

When run with an argument:

$ ./test foo
{CONFIG: foo}
false

When run with the argument nil (a string which just happens to be nil):

$ ./test nil
{CONFIG: nil}
false

So how do we test for args["CONFIG"] being nil, as distinct from the string "nil"?

You could sort this out by providing a proc isNil*(v: Value): bool which returns false except for kinds vkStr and vkList, and returns true for those kinds only when the corresponding field is actually nil.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants
You can’t perform that action at this time.