No description
- Lua 92.6%
- Shell 7.4%
| .gitignore | ||
| current.txt | ||
| melon.lua | ||
| mycoder_help_output.txt | ||
| PRD.md | ||
| PROMPT.md | ||
| ralph-mycoder.sh | ||
| ralph.md | ||
| ralph.sh | ||
| README.md | ||
| test.lua | ||
| VISION.md | ||
melon.lua 🍈
A lightweight, zero-dependency, modular utility library for Lua 5.1 and LuaJIT. Designed for clean developer ergonomics in environments like LÖVE2D, CLI tools, embedded scripting, and game engines.
melon.lua also serves as the proving ground for the Ralph Loop autonomous agent harness.
Features
- Zero External Dependencies: Pure Lua compatible with Lua 5.1, LuaJIT 2.1, and modern Lua engines.
melon.table: Standard functional and associative table helpers (keys,values,map,filter,clone,merge).melon.string: Common string manipulation routines (trim,startswith,endswith,split).melon.fn: Functional programming combinators (compose,curry,memoize).melon.emitter: Lightweight event bus / pub-sub dispatcher (on,off,emit,once).
Installation
Simply copy melon.lua into your project tree, or add it to your package.path:
local melon = require('melon')
API Reference & Usage Examples
1. Table Utilities (melon.table)
local tbl = require('melon').table
-- keys & values
local dict = { name = "Lua", fast = true }
local k = tbl.keys(dict) -- { "name", "fast" }
local v = tbl.values(dict) -- { "Lua", true }
-- map
local nums = { 1, 2, 3 }
local doubled = tbl.map(nums, function(x) return x * 2 end) -- { 2, 4, 6 }
-- filter
local evens = tbl.filter({ 1, 2, 3, 4, 5, 6 }, function(x) return x % 2 == 0 end)
-- { 2, 4, 6 } (compact sequential array)
-- clone (shallow or deep)
local orig = { a = 1, nested = { b = 2 } }
local shallow = tbl.clone(orig) -- shallow copy
local deep = tbl.clone(orig, true) -- recursive deep copy
-- merge
local base = { host = "localhost", port = 80 }
local config = tbl.merge(base, { port = 8080, ssl = true })
-- { host = "localhost", port = 8080, ssl = true }
2. String Utilities (melon.string)
local str = require('melon').string
-- trim
str.trim(" hello world \n") -- "hello world"
-- startswith & endswith
str.startswith("https://example.com", "https://") -- true
str.endswith("archive.tar.gz", ".gz") -- true
-- split
local parts = str.split("apple,banana,orange", ",")
-- { "apple", "banana", "orange" }
local chars = str.split("hello", "")
-- { "h", "e", "l", "l", "o" }
3. Functional Combinators (melon.fn)
local fn = require('melon').fn
-- compose: right-to-left function composition: compose(f, g)(x) == f(g(x))
local add1 = function(x) return x + 1 end
local mul2 = function(x) return x * 2 end
local calc = fn.compose(add1, mul2)
print(calc(3)) -- (3 * 2) + 1 = 7
-- curry: transform multi-argument function into a chain of single/partial applications
local add = fn.curry(function(a, b) return a + b end)
local add5 = add(5)
print(add5(10)) -- 15
print(add(2, 3)) -- 5 (also supports uncurried batch arguments)
local sum3 = fn.curry(function(a, b, c) return a + b + c end, 3)
print(sum3(1)(2)(3)) -- 6
print(sum3(1, 2)(3)) -- 6
-- memoize: cache function results by argument signatures
local expensive = fn.memoize(function(n)
-- heavy computation
return n * n
end)
print(expensive(100)) -- calculated
print(expensive(100)) -- returned immediately from cache
-- memoize with custom key generator
local lookup = fn.memoize(function(entity)
return entity.score * 10
end, function(entity)
return entity.id
end)
4. Event Dispatcher (melon.emitter)
local emitter = require('melon').emitter
-- Register an event listener
local function on_login(user)
print("Welcome " .. user.name)
end
emitter.on("user:login", on_login)
-- Emit an event with arbitrary arguments
emitter.emit("user:login", { name = "Alice" })
-- One-time listeners
emitter.once("app:ready", function()
print("Application initialized!")
end)
emitter.emit("app:ready")
emitter.emit("app:ready") -- No-op, listener already unbound
-- Remove a listener or clear all listeners for an event
emitter.off("user:login", on_login)
emitter.off("user:login") -- unbind all handlers for "user:login"
Running Unit Tests
The test suite validates compatibility across both standard Lua 5.1 and LuaJIT 2.1:
# Using standard Lua
lua test.lua
# Using LuaJIT
luajit test.lua
All test assertions run autonomously and report summary statistics.
Architecture & Ralph Loop
melon-lua is structured to adhere to the Ralph Loop autonomous engineering pattern:
VISION.md: High-level purpose and architectural design principles.PRD.md: The single source of truth task checklist executed iteratively by clean agent sessions.PROMPT.md: System instructions for atomic task execution and verification.ralph-mycoder.sh: Loop runner orchestrating tasks until project completion.
License
MIT License.