RAII cleanup with ?b? (ebo)
?b? (Yoruba: "sacrifice/offering") ensures cleanup code runs automatically when resources go out of scope. It's similar to:
deferwithDrop// Declare resource with automatic cleanup
ebo "database";
// Open connection
ayanmo conn = db.connect();
// Do work...
conn.query("SELECT * FROM users");
// When scope ends, cleanup runs automatically
// Connection is closed, resources freed
// Create RAII guard with cleanup function
ayanmo guard = Ebo.new("tempfile", || {
Odi.delete("temp.txt");
Irosu.fo("Temp file deleted");
});
// Create temp file
Odi.write("temp.txt", "temporary data");
// Do work with temp file...
// When guard goes out of scope:
// ? Cleanup runs automatically
// ? "Temp file deleted" is printed
ayanmo guard = Ebo.new("lock", || release_lock());
// Decide to keep the lock
guard.dismiss(); // Cleanup will NOT run
// Lock remains acquired
ayanmo guard = Ebo.new("cache", || cache.flush());
// Force cleanup now instead of waiting
guard.sacrifice(); // Runs immediately
// After sacrifice, guard is dismissed
// Wrap a value with automatic cleanup
ayanmo scoped = EboScope.new(
Odi.open("data.txt"),
|file| file.sync() // Cleanup function
);
// Use the file
scoped.write("Hello");
scoped.write("World");
// When scoped drops:
// ? file.sync() called automatically
// ? File is properly saved
ise with_lock(lock, work) {
lock.acquire();
ebo "lock"; // Auto-release
work(); // Do protected work
// Lock released when scope ends
}
ise with_temp_file(work) {
ayanmo path = "/tmp/" + Irete.uuid();
ayanmo guard = Ebo.new("temp", || {
Odi.delete(path);
});
Odi.write(path, "");
work(path);
// File deleted automatically
}
ise with_connection(db_url, work) {
ayanmo conn = DB.connect(db_url);
ayanmo guard = Ebo.new("db", || {
conn.close();
});
work(conn);
// Connection closed on return
}