Categories
Computers Lua Programming

Case Insensitive lua Methods

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.

Leave a Reply

Your email address will not be published. Required fields are marked *