I’ve been working on a lua library to support IMAP4Rev1 command exchanges with an IMAP server. Towards that end, I’ve created a lua object. Now, I’d known a little about using lua and the flexibility of lua table since my window manager uses it as a configuration language. Until this project; however, there has been no reason for me to delve into the deeper depths of lua tables.
Now that I have, I’m not sorry as I’ve learned quite a bit of interesting techniques. Below the fold is a rather simple trick to make lua methods case insensitive.
Here’s all the code that’s required:
MyObject = {}
function MyObject.new(self)
o = {}
setmetatable(o, self)
self.__index = function(t, k)
m = self[k]
if not m then m = self[k:lower()] end
if m then return m end
end
end
return o
end
That’s it. Really. In fact, this code will turn any combination of upper and lower case method calls into a valid method call. The only catch is that all methods must be defined as lower case. Such as:
function MyObject.print(self, s)
print(s)
end
Also note that the __index
function as defined above returns no value if a match is not found. That’s not an oversight. If the function returns a nil
value then lua treats that as the result of the lookup and doesn’t throw an error. By returning no value at all, lua detects an error condition and throws the error immediately for the invalid call or data access.
It’s always interesting to play around with stuff like this. It expands one’s computer programming horizons substantially.
ADDENDUM:
The __index
function can be rewritten like so:
self.__index = function(t, k)
m = self[k:lower()]
if m then
return m
else
return self[k]
end
end
Depending on your disposition, this version reads a bit better plus it has the virtue of throwing an error despite the return in the else
. The reason is because the lookup done in the self
table fails and causes the error to be thrown, not the __index
function call itself.
So, in summary, to force an error for a failed lookup either don’t return a value at all or return the result of a subsequent table lookup that should fail.