Skip to content

Commit

Permalink
Allow nil to be substituted for false in some SetxxxOption functions
Browse files Browse the repository at this point in the history
  • Loading branch information
nickgammon committed Jul 10, 2010
1 parent a6f49a1 commit 6226850
Showing 1 changed file with 4 additions and 0 deletions.
4 changes: 4 additions & 0 deletions scripting/lua_methods.cpp
Expand Up @@ -291,6 +291,8 @@ LUALIB_API const char *get_option_value (lua_State *L, int narg) {
// if boolean convert to 0 or 1
if (lua_isboolean (L, narg))
return (lua_toboolean (L, narg) ? "1" : "0");
else if (lua_isnil (L, narg))
return "0"; // nil is considered false

const char *s = lua_tolstring(L, narg, NULL);
if (!s)
Expand Down Expand Up @@ -4904,6 +4906,8 @@ static int L_SetOption (lua_State *L)
// if boolean convert to 0 or 1
if (lua_isboolean (L, 2))
option = lua_toboolean (L, 2) ? 1 : 0;
else if (lua_isnil (L, 2))
option = 0;
else
option = my_checknumber (L, 2);

Expand Down

7 comments on commit 6226850

@Twisol
Copy link
Contributor

@Twisol Twisol commented on 6226850 Jul 10, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By using lua_isnil() instead of lua_isnoneornil(), passing 'nil' becomes different from passing nothing, even though in pure Lua it's semantically equivalent. That kind of bothers me here.

And honestly, I can't think of many situations where you'd rather pass nil instead of false. The intent of 'false' is much clearer.

@nickgammon
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't you think that it is a tiny bit misleading to have:

SetOption ("foo")

clear the option?

However if you have a variable, like this:

x = nil ... or x = false

then:

SetOption ("foo", x)

That sets foo to x, and if x is nil then it is considered false, as in the rest of Lua.

@Twisol
Copy link
Contributor

@Twisol Twisol commented on 6226850 Jul 10, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think it's misleading, but treating ("foo", nil) as different from ("foo") breaks normal expectations about how Lua works, and is inconsistent with what you see elsewhere. Given the above, the two possibilities are treating both forms as passing false, or treating them both as invalid. In the end, I'd simply prefer to treat nil as invalid, because I'm not sure there's any reason not to use false in any circumstance. 'nil' is more of an undefined value, a neither-or, and in general I prefer it that way.

EDIT: As far as I recall, the only place 'nil' is considered a false value is in conditionals. Passing nil as a parameter generally means something different, because it's impossible to "pass" nothing to a conditional after all. And like I said, treating nil and "none" as different really bothers me, because pure Lua has no faculty to differentiate between the two; it's something only the C API lets you do, and in general there's little reason to differentiate between them.

@nickgammon
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can distinguish between nil and false, because you can test if x == nil (for example).

There are a couple of places in the existing Lua API where some functions actually return nil (by pushing nil) and others return "no value" by not pushing anything. These can occasionally cause confusion, I admit.

However in this case (and remember this doesn't affect any existing scripts, excepting ones that don't currently work), I think it is more useful for allowing scripters to serialize options (eg. SetOption ("foo", x) ) where x may be supplied (eg. in a table). However in the normal Lua tradition, omitting a value from a table is pretty-much the equivalent of saying that the value is false (for boolean values I mean).

I reiterate that using lua_isnoneornil () would be even more confusing, as you would then have SetOption ("show_italic") as clearing the option "show_italic", not setting it, which I think just looks crazy. I also don't think you would write SetOption ("show_italic", nil) as such, because that looks silly, but SetOption ("show_italic", options.show_italic) is somewhat more likely, and options.show_italic might be nil.

@Twisol
Copy link
Contributor

@Twisol Twisol commented on 6226850 Jul 10, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused. I said you can't distinguish between nil and none in pure Lua, not nil and false. I also said I'd prefer not to treat nil as false by default.

Your point about serializing options is interesting... I'm not sure how often a plugin needs to save a world option itself, though. And you can easily use "x or false" to provide an (explicit) default of false.

Your "nonexistant table entry == false" point is a bit specific to the situation the table is being used in. I could have a list of people I know, and use 'true' to mark them as friends, and 'false' to mark them as enemies. Nonexistent entries are just people I don't know .

I do agree that using lua_isnoneornil() here would be strange (though I still say it keeps consistency), which is why I'd rather not accept nil at all. Like I said, "x or false" is perfectly valid (I tested).

@nickgammon
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In pure Lua you can distinguish like this:

function f (...)
print (select ("#", "..."));
print (select (1, ...));
print (select (2, ...));
end -- f

f ("hello")
f ("world", nil)

I don't want to get into a lengthy debate about it - people are unlikely to pass nil as an argument (particularly directly) but for the serialization - well who knows? For example, you may have stored in a variable whether you want, or not, a trigger to have keep_evaluating to be true or false, and the initial, default, value of an unassigned variable will be nil.

@Twisol
Copy link
Contributor

@Twisol Twisol commented on 6226850 Jul 10, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eww, that's just nasty... (I don't think select() is implemented in pure Lua, though. :D)

Fair enough. Just wanted to voice that concern, thanks for detailing your thought process for me.

Please sign in to comment.