It was pointed out to me that this example from the fetch chain post is a little funny-looking:

deep.
  fetch(:foo, {}).
  fetch(:baz, {}).
  fetch(:qux)

and it is, so let’s talk about it!

One thing I like about fetch chains is that I can control how “delicate” they are, and under what circumstances they raise errors. This example only raises an error if :qux is missing, regardless of whether :foo or :bar were also missing. Although I’m sure I’ve written a fetch chain like this, it probably wasn’t a good idea, since the error could be seen as misleading.

A more robust version would have gone like this:

deep.
  fetch(:foo, {}).
  fetch(:baz, {}).
  fetch(:qux, nil)

No errors raised, unless we really, really needed a non-nil value out of deep. But if we wanted that level of robustness, we really should have used dig instead of a fetch-chain.

A more likely scenario than the given example would be where we require :foo and :bar but want to make :qux optional, so we’d do this:

deep.
  fetch(:foo).
  fetch(:baz).
  fetch(:qux, nil)

As unlikely to be useful as they are, it doesn’t seem impossible that circumstances exist where other combinations of optionality and delicacy are useful. Maybe even something a bit silly like the first example, but perhaps even sillier like this:

deep.
  fetch(:foo).
  fetch(:baz, {}).
  fetch(:qux)

If find yourself writing one, it’s probably a great idea to leave a comment about why it matters.

I’m glad this came up, and I think it’s the kind of thing that could be worth exploring a bit more. Exceptions and breaks are one of the consequences of optional values, usually unintended consequences, but not always.