#tools
16 posts
Morse code: one table, two ambiguities, three details
Morse itself is trivial; the trouble is in the details — who owns the space, how to normalise full-width dots, and how long one unit actually is.
Atomic file writes: write a temp file, then rename
Overwriting in place leaves half a file behind on power loss, a crash, or a concurrent read. A temp file plus rename uses filesystem atomicity to make half a file impossible.
Base64: it is neither encryption nor compression
Base64 turns 3 bytes into 4 printable characters, growing the payload by a third. It solves carrying binary through a text channel, not keeping anything secret.
Debounce vs throttle: the difference is who decides when to run
Both limit how often a function runs. Debounce lets the last call decide the moment; throttle uses a fixed window. The wrong pick shows up as a laggy drag or a request every 200ms.
Estimating work: why "about three days" becomes three weeks
You estimated writing code; what you owe is writing plus integration, review, rework, and waiting on others. Listing the unknowns beats multiplying every day count by two.
Feature flags are debt, not configuration
Every flag doubles the reachable code paths and no flag ever gets deleted by itself. Giving each one a removal date matters far more than building a clever flag system.
git bisect: turn which commit broke it into one command
The hard part of regression hunting is not the binary search, it is defining what counts as broken. Write a script that answers that, and bisect compresses n builds into log n.
Semantic versioning: a major bump promises no silent behavior change
MAJOR does not mean big. It means breaking. Using it for refactors and hiding breaks in minor releases turns your downstream automatic upgrades into outages.
What technical debt interest actually looks like
Debt is not ugly code; it is the extra cost every future change pays. The test is measurable: files touched per edit, test runtime, places that must change together.
Writing a cron parser: five fields, the union rule, and February 30th
The syntax takes half an hour. The semantics are the work: day-of-month and day-of-week unite rather than intersect, impossible dates need a stopping condition, and 7 and 0 are both Sunday.
CSV is not split on commas: quoting and newlines from RFC 4180
The moment a field is quoted, split stops working: quotes hold delimiters and newlines, and a quote inside a field is doubled. A thirty-line state machine beats any regex.
Base and unit conversion: temperature is the only non-linear one
Converting between bases 2 and 36 needs BigInt to avoid silent precision loss. Across ten unit categories nine are linear ratios, while temperature is affine, and a single multiplier is always wrong.
Color and contrast: relative luminance is not an average
Converting between notations is just the entry point. The real trap is WCAG contrast, which needs gamma decoding before weighting, and deciding between black and white text, which is not a brightness threshold.
Hash and checksum: why CRC32 and MD5 have to be written by hand
The browser only offers the SHA family, and only in a secure context. CRC32 and MD5 are not in Web Crypto. Along the way: large files should not be read into memory whole, and checksums should not be compared by eye.
Regex Lab: hits, groups, replacement preview, and the zero-width trap
A regex tester has to do three things well: show where matches land and what each group captured, preview the replacement, and never hang on a zero-width match.
JSON Studio: format, validate and diff in one page
Built from the habit of writing throwaway commands to clean up JSON. It formats, minifies, sorts, pinpoints parse errors by line and column, and diffs two documents — all in the browser.
