Metatableless classes?

Hello. I’ve been tinkering around with the idea of lua classes without the need of metatables. From what I have heard, accessing values through the __index metamethod can be slow. So this is what led me to try and test my own class implementation; one in which the data table directly references the method functions. Now, the question is: am I being stupid, or would this actually work and if so, what are the caveats/positives with this approach?

-- person class
local methods = {}

function methods:say_hello()
    print(string.format("Hello, my name is %s. Nice to meet you!", self.name))
end

local function new_person(name)
    local data = {
        name = name
    }

    -- Reference the methods in our data table:
    for k, v in pairs(methods) do
        data[k] = v
    end

    return data
end

-- Usage

local bob = new_person("bob")
local laura = new_person("laura")

bob:say_hello()
laura:say_hello()

Sorry for bumping… just hope I can get some sort of reply.

For anything you’re concerned about the performance of, do the following:

Ask yourself: Does it matter?

  • If it doesn’t then implement it whichever way you think is best.
  • If it does, benchmark each option to see which is the fastest and then decide based on those results.

When you say __index is slow, you probably heard that assigning a function to __index is slow. A table on the other hand is pretty fast and probably used most often.

The following should be suitable for most use-cases.

local Class = {}
Class.__index = Class

function Class:myMethod()

end

You can of course do what you were asking about, in which case you’re sacrificing memory in return for speed. The reality is, when __index is a table, the speed you gain is probably negligible in comparison to memory usage. Your method only requires a single lookup but a field in the table for each method, while __index requires fetching the metatable and performing the same lookup.

2 Likes