Defimpl with redefinition overriding existing implementation

I wrote a sample module that overrides Jason.Encoder.encode protocol for Map.

defmodule JsonEncoder do
  defimpl Jason.Encoder, for: Map do
    def encode(value, opts) do
      IO.inspect(PASSINGHERE)

      value
      |> Enum.filter(fn {k, _v} -> k != :c end)
      |> Jason.Encode.keyword(opts)
    end
  end

  #test call
  def enc() do
    %{a: 1, b: 2, c: 3} |> Jason.encode!()
  end
end

While doing the same for a custom struct was working, when I do it for generic Map type, it doesn’t.
I can see the compiler detects the redefinition:

iex(8)> recompile
Compiling 1 file (.ex)
    warning: redefining module Jason.Encoder.Map (current version loaded from _build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Map.beam)
    │
  2 │   defimpl Jason.Encoder, for: Map do
    │   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    │
    └─ test/support/json_encoder.ex:2: Jason.Encoder.Map (module)
Generated sampleapp app
:ok

but when I run the test call, I don’t see my code to be triggered.

iex(9)> JsonSortedEncoder.enc
"{\"c\":3,\"a\":1,\"b\":2}"
iex(10)>

What am I missing?

Thanks in advance

Overriding protocol implementations is afaik not something elixir wants you to do. I’d stay away from that.

Jason has Jason.OrderedObject — jason v1.5.0-alpha.2 for your usecase.

1 Like