Start every script with the same skeleton: strict error mode (errexit, nounset, pipefail), an IFS reset, and a main() function. Catches silent failures that have lost engineers weeks of debugging.
Three common patterns: load it all into memory, iterate line-by-line, or stream bytes. Pick by file size — `read_to_string` is convenient but bad for huge files.
Write to a temp file in the same directory, then `Files.move` with `ATOMIC_MOVE` to the target. Readers never see a half-written file — critical for config / state files.
Idiomatic helpers for reading + writing JSON to disk, with atomic writes and pretty-printed output. Catches the common "edit and save → corrupt file on crash" failure mode.
For large files or line-oriented protocols, wrap a Reader/Writer in `Buffered*`. Reduces per-call overhead from many small reads to fewer large ones. Always close with try-with-resources.
Merge two associative arrays at any nesting depth — like array_merge_recursive, but later values OVERWRITE earlier ones at the leaf level instead of combining them into arrays. Perfect for config-file overrides.
Convert a string to title case while keeping common short words (a, an, the, of, etc.) lowercase — unless they appear at the start or end of the title.
`=` returns NULL when either side is NULL. `IS DISTINCT FROM` (and its inverse `IS NOT DISTINCT FROM`) treat NULLs as equal to themselves — the right tool for change detection.
Time a closure with microsecond precision and return both its result and the elapsed milliseconds. Great for quick perf experiments without pulling in a profiler.