lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


I've recently struggled with this problem.

I want to create inheritance of environments. I set the parent environment
as __index for the child environment. So when you access a variable from the
child environment that's not there, it will look at the parent. Pretty
standard stuff - kind of like scopes and namespaces work in C++.

Let's say the parent has {a=5, b=10}. The child has {a="five", c=true}. If I
access "a" I will get "five" instead of 5. So far so good. The two a's are
two very different variables. But if I set the child's a to nil, I will
start using the one from the parent because there is no way to distinguish
between "not defined" and "defined, but currently nil":
print(a) -> five
a=nil
print(a) -> 5

In contrast local variables work differently. If I have a global 'a' and a
local 'a', then if the local variable is nil using 'a' will still refer to
the local variable and not the global.

So my solution for now is to use local variables in the global chunk. But
there are limitations: there's a limit for how many local variables I can
have in a chunk, how many upvalues a function can have, and also I can't
have multiple source files sharing the same environment (because each
becomes its own chunk). Also there is a problem with using a solution like
Pluto for persisting the state. Since many functions have upvalues, they
have to be saved together with their bytecode, which seriously bloats the
size of the state.

Ivo

-----Original Message-----
From: lua-l-bounces@lists.lua.org [mailto:lua-l-bounces@lists.lua.org] On
Behalf Of Kevin Martin
Sent: Tuesday, March 19, 2013 4:29 PM
To: Lua mailing list
Subject: Re: Undefined variables returning nil


On 19 Mar 2013, at 22:53, William Sumner wrote:

It was meant as a rhetorical question, to ask yourself. However, to comment
on your suggestions:

1) The contains function is clearly a bad idea. How would you implement it?
2) The in operator is better-ish, the first question that comes to mind is
how you would modify the C API, as lua_gettable/etc can no longer push nil.

However, I'm just trying to give you things to think about, I'm not
interested in engaging in a serious discussion.

If you really want to make this change, you are quite welcome as someone has
already said.

I guess my main objection is that I don't actually think there's a problem.
I don't see the unsafeness. I also don't think you have explained why it is
unsafe, only stated that it is unsafe.

1) nil literally means no-value. Is it not reasonable for a table access to
return no-value when there is no value to return?
2) Any attempt to do anything with a nil value yields an error, so if
getting the nil value was a mistake as your error is trying to catch, the
error will be produced as soon as you try and do anything with the value,
see below. Is this so far from you error?
3) Not handling the case of no-value is definitely an error, but that is bad
programming, nothing to do with the language.

Kev

-------------------------------------------

> do
>> local x = nil
>> print(x+5)
>> end
stdin:3: attempt to perform arithmetic on local 'x' (a nil value) stack
traceback:
	stdin:3: in main chunk
	[C]: in ?
> 

> do
>> local x = nil
>> x()
>> end
stdin:3: attempt to call local 'x' (a nil value) stack traceback:
	stdin:3: in main chunk
	[C]: in ?
> 

> do
>> local x = nil
>> print(x.a)
>> end
stdin:3: attempt to index local 'x' (a nil value) stack traceback:
	stdin:3: in main chunk
	[C]: in ?
>