Search code examples
rubysyntaxlaw-of-demeter

Do the 'Array#dig' or 'Hash#dig' methods violate the Law of Demeter?


The dig method:

Extracts the nested value specified by the sequence of idx objects by calling dig at each step, returning nil if any intermediate step is nil.

This means that:

[1, {foo: :bar}].dig(1, :foo)

returns :bar by performing a lookup on an Array object and on the Hash object in turn.

The first call to dig is made on an Array object but the next call to dig is made on the Hash object returned from the Array.

Does the use of dig not violate the Law of Demeter?


Solution

  • dig is pretty much just syntactic sugar on the array and hash accesses you performed before the method was introduced, so it doesn't violate the Law of Demeter any more or less than you already were. Consider your example:

    [1, {foo: :bar}].dig(1, :foo)
    [1, {foo: :bar}][1][:foo]
    

    You have the same data structure, you're getting the same value, but pleasantly, now you don't have to check for nil every step of the way too.

    The Law of Demeter is a design heuristic. If you find yourself reaching through three objects to accomplish something, the code doing the reaching has to know things about all three of those objects. It's a sign that you might want to refactor to reduce the number of dependencies your modules have, but the method you use to do the reaching, whether [] or dig, isn't entirely relevant.