Struct Embedding in Lua
Lua supports tables, which can be used to create structures similar to structs in other languages. While Lua doesn’t have built-in support for object-oriented programming, we can use tables and metatables to achieve similar functionality.
-- Define a base table (similar to a struct)
local base = {}
base.__index = base
function base.new(num)
local self = setmetatable({}, base)
self.num = num
return self
end
function base:describe()
return string.format("base with num=%d", self.num)
end
-- Define a container table that "embeds" base
local container = {}
container.__index = container
function container.new(num, str)
local self = setmetatable({}, container)
self.base = base.new(num)
self.str = str
return self
end
-- "Inherit" methods from base
setmetatable(container, {__index = base})
-- Main function
local function main()
-- Create a new container instance
local co = container.new(1, "some name")
-- Access fields
print(string.format("co={num: %d, str: %s}", co.base.num, co.str))
-- Access the base's num field directly
print("also num:", co.base.num)
-- Call the describe method
print("describe:", co:describe())
-- In Lua, we don't need to explicitly define interfaces.
-- Any table with a 'describe' method can be treated as a "describer".
local function printDescriber(d)
print("describer:", d:describe())
end
-- Pass the container as a "describer"
printDescriber(co)
end
-- Run the main function
main()
To run this Lua script, save it as struct_embedding.lua
and execute it with the Lua interpreter:
$ lua struct_embedding.lua
co={num: 1, str: some name}
also num: 1
describe: base with num=1
describer: base with num=1
In this Lua implementation, we’ve simulated struct embedding using tables and metatables. The base
table acts as our base “struct”, and the container
table “embeds” it by storing an instance of base
as one of its fields.
We use Lua’s metatables to implement method inheritance, allowing container
to access methods from base
. This is similar to how embedding works in other languages, where the embedding struct can call methods of the embedded struct.
Lua doesn’t have a built-in concept of interfaces, but we can achieve similar functionality by simply expecting objects to have certain methods. In this example, any table with a describe
method can be passed to the printDescriber
function, mimicking the behavior of interfaces in statically-typed languages.
This example demonstrates how Lua’s flexible nature allows us to implement concepts from other languages, even when they’re not built into the language itself.