I have problems with consolidation of protocol implementation in my Elixir project. To be more specific I use Ecto
and some simple project called Gold
(doesn't matter much atm). The problem is, both of them (Ecto
and Gold
) use Poison
to serialize Decimals
(and implement proper Protocol).
Implementation for Ecto
looks somewhat like this:
defimpl Poison.Encoder, for: Decimal do
def encode(decimal, _opts), do: <<?", Decimal.to_string(decimal)::binary, ?">>
end
During development there is a warning saying that the module is duplicated:
warning: redefining module Poison.Encoder.Decimal (current version loaded from /(...)/_build/dev/lib/gold/ebin/Elixir.Poison.Encoder.Decimal.beam)
lib/ecto/poison.ex:2
But when I try to use for instance exrm
to build a release, then I get errors saying that I have duplicate_modules
===> Provider (release) failed with: {error,
{rlx_prv_assembler,
{release_script_generation_error,
systools_make,
{duplicate_modules,
[{{'Elixir.Poison.Encoder.Decimal',
gold,
"/(...)/rel/bitcoin_api/lib/gold-0.12.0/ebin"},
{'Elixir.Poison.Encoder.Decimal',
ecto,
"/(...)/rel/bitcoin_api/lib/ecto-2.0.2/ebin"}}]}}}}
How should I deal with this? The case here is I actually use my own version of Gold
, so I can tamper with it to fix it asap. I know I can just add Ecto
to Gold
as a dependency, but that seems a bit overkill to just implement one Protocol like this. Isn't there some kind of a macro to check if a module has already been implemented?
A quick fix could be to wrap Gold's implementation in a Code.ensure_loaded?/1
unless Code.ensure_loaded?(Ecto) do
defimpl Poison.Encoder, for: Decimal do
def encode(decimal, _opts), do: <<?", Decimal.to_string(decimal)::binary, ?">>
end
end
Its a little icky but then you don't have to add Ecto, but just check if something else already pulled it in
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With