When Your Hash Becomes a String: Hunting Ruby’s Million-to-One Memory Bug