Like python's magic methods, Lua allows an object to define its behavior for certain operators. These definitions are simply functions, which are referred to as metamethods. The metamethods are placed as the values of specific keys in an object's metatable. A metatable is an ordinary Lua table. For instance, the metamethod that defines the '+' operator is installed as the value for key __add in the metatable..
In the example below, we create a Lua module that exports a class called Element that represents a value in the finite field of integers modulo 7. This is merely modulo arithmetic. Since the Element class serves as its own metatable, we can simply define the metamethods on the object itself.
finitefield.lua
-- ==============================================
-- finite field of integers modulo prime (7)
-- ==============================================
-- module setup
local modname = ...
local M = {}
_G[modname] = M
package.loaded[modname] = M
-- import section
local error = error
local getmetatable = getmetatable
local setmetatable = setmetatable
local string = string
local tostring = tostring
-- no more external access after this point
setfenv(1, M)
-- private
local MODULO = 7
-- public
Element = {}
function Element:new(n)
local o = {}
setmetatable(o, self)
self.__index = self
o.val = n % MODULO
return o
end
function Element:__tostring()
return string.format("%d", self.val)
end
function Element:__concat(s)
return tostring(self) .. tostring(s)
end
function Element:__add(other)
if getmetatable(other) ~= getmetatable(self) then
error("attempt to 'add' an element with a non-element")
end
local val = self.val + other.val
return Element:new(val)
end
function Element:__mul(other)
if getmetatable(other) ~= getmetatable(self) then
error("attempt to 'multiply' an element with a non-element")
end
local val = self.val * other.val
return Element:new(val)
end
function Element:__lt(other)
return self.val < other.val
end
function Element:__lt(other)
return self.val < other.val
end
function Element:__eq(other)
return self.val == other.val
end
example
#!/usr/bin/env lua
local ff = require 'finitefield'
local a = ff.Element:new(5)
local b = ff.Element:new(8)
local c = a + b
print(a .. ' + ' .. b .. ' = ' .. c)
local d = a * b
print(a .. ' * ' .. b .. ' = ' .. d)
output
5 + 1 = 6 5 * 1 = 5
No comments:
Post a Comment