← Back to blog

Welcome to RubyHash

· Lachlan Young

If you’ve ever worked with Minitest (or any Ruby testing framework), you’ve probably seen a failing assertion dump two hashes into your terminal that look something like this:

-{"uid"=>"darrick@dickens.test", "allow_password_change"=>true, "name"=>"Darrick", "nickname"=>"d", "image"=>nil}
+{"uid"=>"darrick@dickens.test", "allow_password_change"=>false, "name"=>"Darrick", "nickname"=>"d", "image"=>nil}

Somewhere in those two nearly identical lines, one value changed. Spotting it is genuinely painful, especially when the hashes are large, deeply nested, or the keys come back in a different order each run. You end up dragging your finger across the screen comparing characters, which is exactly the kind of work a computer should be doing for you.

RubyHash exists to do that work. This post is a quick tour of what it does, why I built it, and how to get the most out of it.

What RubyHash does

Paste the two lines (keep the - and + prefixes straight from your console) and RubyHash will:

  1. Parse the Ruby hash syntax into a real data structure, not a string approximation.
  2. Convert it to JSON and sort the keys alphabetically, so ordering differences stop masquerading as real differences.
  3. Render a side-by-side diff with word-level highlighting, so the one value that actually changed lights up.
  4. Flag type changes, so a field that went from nil to a string, or from an integer to a hash, gets called out explicitly.

The result for the example above is immediate: allow_password_change flipped from true to false, and nothing else moved. No squinting required.

Why a real parser matters

It would be tempting to solve this with a regular expression that swaps => for : and calls it a day. That approach falls apart the moment your data gets interesting. Ruby hash output is full of edge cases:

RubyHash uses a hand-written recursive descent parser that walks the input character by character and understands the grammar of a Ruby hash. That means it handles the nesting and the quoting correctly instead of guessing, which is the difference between a diff you can trust and one that occasionally lies to you.

How to use it

Using it takes about ten seconds:

  1. Copy the diff output straight from your test runner, including the - and + prefixes.
  2. Paste it into the text area on the home page.
  3. Click Compare.

You can toggle between a side-by-side view and a unified view depending on how wide your hashes are, and copy the cleaned-up JSON back out if you want it for a bug report or a code review.

That’s the whole flow. No sign-up, no installation, no extension to add to your editor. Everything runs in your browser, which also means your data never leaves your machine. The hashes you paste are not sent to a server, logged, or stored anywhere.

Where this fits

RubyHash started as a tool I needed for my own Rails work, where serialization tests and ActiveRecord comparisons routinely produce hashes too big to eyeball. Over time it grew a blog alongside it, covering the Ruby and Rails topics that come up while writing and debugging this kind of code: testing culture, pattern matching, Enumerable, hash defaults, error handling, and more.

If a failing test just dumped a wall of hashrockets in your terminal, head to the home page, paste it in, and let RubyHash show you exactly what changed. And if you want more Ruby in your inbox, the blog is where new articles and tools land.

Happy hashing.

Enjoyed this post?

Subscribe to get notified when we publish more Ruby and Rails content.