lua-users home
lua-l archive

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


On 23 August 2010 18:10, HyperHacker <hyperhacker@gmail.com> wrote:
> On Mon, Aug 23, 2010 at 07:55, Matthew Wild <mwild1@gmail.com> wrote:
>> On 23 August 2010 13:25, Cuero Bugot <cbugot@sierrawireless.com> wrote:
>>>> Actually it is:
>>>>    debug.setmetatable(nil, { __index = {} })
>>>> You could turn this into a function to turn the feature on and off for
>>>> certain sections of code.
>>>
>>> Indeed this is a way to do it, but it is rather intrusive :) The fact is that I cannot isolate part of the code need this "safe navigation operator" or not, since it is usually embedded in the code here and there.
>>>
>>
>> Maybe it's intrusive, maybe not. I've been toying with the idea of
>> making it default in my application. Thinking logically though:
>>
>> 1) That there is any code that relies on nil indexing throwing an
>> error is rather unlikely, because it's a very inconvenient place to
>> throw an error, especially as there is no way from the error to tell
>> where in the chain the nil was found.
>>
>> 2) If the code doesn't check each stage then it makes no substantial
>> difference whether the first or the last index in the chain returns
>> nil. With this metatable hack it will always act as if it was the last
>> that returned nil, that's all.
>>
>> 3) No other aspect of nil is changed, so using it in other places will
>> still trigger an error (trying to call it for example). As an aside,
>> adding a __call to nil would be something I /did/ disagree with,
>> because function calls are expected to *do something*.
>>
>> 4) Code that is already checking each individual step of the index
>> chain remains unaffected by the change.
>>
>> 5) As far as I can see this is the only "real" solution to your
>> problem. You want to be able to index a nil value, and Lua provides
>> you with a way to do exactly that.
>>
>> However all this said, I still haven't enabled it in my code. Maybe
>> I'm just a chicken :)
>>
>> Matthew
>>
>
> I think there are many cases where this could be a problem. Consider
> somewhere along the line you grab a value from a table, but don't
> operate on it just yet - maybe it gets passed through a few levels of
> functions calls, or put into another table for later examination. Now
> suddenly you find this is nil, and you have no idea where it came
> from.
>

But is that really different to:

   a = { b = { c = { d = "Hello world" } } }
   f(a.b.c.e) -- Oops! But I get nil...

So being able to index nil just potentially allows you to make that
mistake in more places, it doesn't mean you'll get nils where you
would never have got them before. And to be honest it's rarely
difficult to look at a traceback and figure out where a nil value
would have come from.

> Of course, if you add an __index to nil that returns nil, but also
> prints a warning (using debug.getinfo or some such to state where the
> index occurred), this is no longer a major problem.
>

Yes, though then if you /do/ start using the feature everywhere,
things are going to get noisy quick :)

You could argue for the same reason for setting an __index on all
tables that logs a warning whenever a nil field is indexed. Sure,
it'll catch some issues, but really, is it worth it?

Matthew