12

我在 Elixir 项目中合并协议实现时遇到问题。更具体地说,我使用Ecto了一些名为Gold(atm 无关紧要)的简单项目。问题是,它们(EctoGold)都Poison用于序列化Decimals(并实现正确的协议)。

的实现Ecto看起来有点像这样:

defimpl Poison.Encoder, for: Decimal do
    def encode(decimal, _opts), do: <<?", Decimal.to_string(decimal)::binary, ?">>
end

在开发过程中,有一条警告说模块重复:

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

但是当我尝试使用例如exrm构建一个版本时,我会收到错误消息说我有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"}}]}}}}

我应该如何处理?这里的情况是我实际上使用了我自己的版本Gold,所以我可以篡改它以尽快修复它。我知道我可以将其添加EctoGold依赖项,但是仅实现一个这样的协议似乎有点过头了。是不是有某种宏来检查模块是否已经实现?

4

1 回答 1

1

一个快速的解决方法可能是将 Gold 的实现包装在一个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

它有点恶心,但您不必添加 Ecto,只需检查是否有其他东西已经将其拉入

于 2020-08-17T13:48:43.783 回答