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