merge namespaces
Problem: you want to have code in multiple files while still giving them the same explicit namespace.
- add to the same root namespace
- copy the methods
- use a global namespace
- provide the namespace as a parameter to the loaded library
solution 1. add to the same root namespace
This is probably the best way to do this:
local arith = require 'arith' require 'add4' require 'mul4' print(arith.add(1, 2)) print(arith.mul(2, 2))
With 'arith.nelua' defining nothing but the namespace:
local M = @record{}
return MAnd 'add4.nelua' and 'mul4.nelua' requiring the same namespace to modify it:
local arith = require 'arith' function arith.add(a: auto, b: auto) return a+b end return arith -- not necessary for this example
local arith = require 'arith' function arith.mul(a: auto, b: auto) return a*b end return arith
solution 2. copy the methods
##[[
local function merge(a, b)
for name, f in pairs(b.value.metafields) do
assert(a.value.metafields[name] == nil)
a.value.metafields[name] = f
end
end
]]
local math = require 'add'
local math1 = require 'mul'
#[merge]#(math, math1)
print(math.add(1, 2))
print(math.mul(2, 2))with add.nelua and mul.nelua written normally:
local M = @record{}
function M.add(a: auto, b: auto) return a+b end
return Mlocal M = @record{}
function M.mul(a: auto, b: auto) return a*b end
return Msolution 3. use a global namespace
This is surely still possible with a Lua-collision name like 'math', but for convenience this example goes with 'mathy' instead.
require 'add' require 'mul' print(mathy.add(1, 2)) print(mathy.mul(2, 2))
-- add.nelua
## if not mathy then
global mathy = @record{}
## end
function mathy.add(a: auto, b: auto) return a+b end-- mul.nelua
## if not mathy then
global mathy = @record{}
## end
function mathy.mul(a: auto, b: auto) return a*b endsolution 4. provide the namespace as a parameter to the loaded library
This is similar to solution #1, but the individual files don't need to know what namespace they're using, they just need to expect it to have been prepared Lua-side.
local arith = @record{}
## M = arith.value
require 'add5'
require 'mul5'
print(arith.add(1, 2))
print(arith.mul(2, 2))With 'add' and 'mul' as oneliners:
function #[M]#.add(a: auto, b: auto) return a+b end
function #[M]#.mul(a: auto, b: auto) return a*b end
This might sound useful for loading a library multiple times to modify multiple namespaces, but require-caching defeats that:
local arith = @record{}
## M = arith.value
require 'add5'
require 'mul5'
local mathy = @record{}
## M = mathy.value
require 'add5'
print(arith.add(1, 2))
print(arith.mul(2, 2))
print(mathy.add(2, 2)) -- error: cannot index meta field 'add' in record 'mathy'