Chain Lua is a small easy to understand functional library implemented as a module that can wrap Lua tables.
Function invocations follow the fluent inteface, enabling method chaining for complex but human readable operations:
Chain=require'Chain'localt1=Chain:with({ foo="bar", one="two", three="four" }) localoutput=t1:merge({ five="six" }):
map(function(k, v) returnk, v.."mapped" end):
reject_unless(function(k, v) returnk=="foo" orv=="sixmapped" end)- Create a new chain with an empty table with
Chain:new() - Wrap an existing table using
Chain:with(...)
When wrapping an existing table, the exisitng meta table is saved and used to lookup fields before Chain:
..localorig_meta_table=getmetatable(t)
index= {
__index=function(g, k)
iforig_meta_tableandorig_meta_table[k] thenreturnorig_meta_table[k]
elseifk=="is_a_chain" thenreturntrueelsereturnself[k]
endend,
__original_meta_table=orig_meta_table,
}
setmetatable(t, index)Unlinking resets the table to its original meta table:
functionChain:unlink()
setmetatable(self, getmetatable(self).__original_meta_table)
returnselfendFunctions that alter the internal table state have two flavours: functions with inline in the title mutate the table while those without implicitly return a new table instance:
functionChain:merge_inline(t)
assert_table(t)
fork, vinpairs(t) doself[k] =vendreturnselfendfunctionChain:merge(t) returnChain:new():merge_inline(self):merge_inline(t) end