Clarification on Question/Exercise regarding extention of protocols

I’ve been working my way through the Protocols chapter of Programming Elixir, and I came across this exercise in the last section of the chapter:

In many cases, inspect will return a valid Elixir literal for the value being
inspected. Update the inspect function for structs so that it returns valid
Elixir code to construct a new struct equal to the value being inspected.

I went ahead and implemented something:

defimpl Inspect, for: Map do
  def inspect(%{__struct__: module} = struct, opts) do
    tents = Map.delete(struct, :__struct__) |> Enum.to_list
    quote do
      defmodule unquote(module) do
        defstruct unquote contents
    |> Macro.to_string

I literally threw this together after writing a small list of steps to be taken based on my understanding of the question, I’ve not assessed the veracity of the inner function here, there is likely a better and faster function than the one I’ve defined but I think the overarching problem is that my scope is too large.

The problem I’m having is that this implementation unfortunately seems to rewrite the entire Inspect.Map implementation module, which messes up a lot other functions and basically makes inspect unusable for my session.

I hoped my implementation would just override the matching function clause, and thus change the way inspect handles structs, but it is instead changing everything about how it handles maps, save for any fallbacks.

I’m also starting to wonder If I’ve understood the exercise itself. Maybe I’m meant to take a more limited approach?

I would really appreciate some guidance.


defimpl Inspect, for: Any instead of defimpl Inspect, for: Map

fixes the issue.

Also I edited my OP message to scope the args to Map.delete due to the pipe ( |> )

iex(7) b = %Blob{content: 123}
defmodule Blob do
  defstruct content: 123

Even though the question is solved, I do wonder why using defimpl Inspect, for: Any would work, given that an implementation for Map exists and it includes maps that contain:__struct__, keys.

Does my defimpl Inspect, for: Any jump to the top of the list?