是否有可能找到实现某些协议的所有模块?

时间:2016-03-01 15:37:14

标签: protocols elixir

我想知道是否有可能找到所有具有特定模块实现的模块?

我有一个简单的协议:

defprotocol Ep.PerformTest do
  @doc "Should return tupple {out, time}"
  def test(struct)
end

很少有能够实现此协议的模块:

defmodule Ep.Test.Rexcpp do
  defstruct [:input, :code, :output]

  def displayName(), do: "Rextester C++"

  defimpl Ep.PerformTest, for: Ep.Test.Rexcpp do
    def test(struct) do

    end
  end
end

2 个答案:

答案 0 :(得分:7)

Protocol.extract_impls/2似乎是您正在寻找的。

  

从给定路径中提取为给定协议实现的所有类型。

感谢OP的评论,以下是问题中示例的代码:

path = :code.lib_dir(:protocol_test, :ebin)
mods = Protocol.extract_impls(Ep.PerformTest, [path])

由于我们在这里调用Erlang :code模块来获取路径,因此模块名称需要采用Erlang使用的原子格式。

答案 1 :(得分:1)

您正在寻找__protocol__/1方法。从文档中:

  

__protocol__/1-返回协议信息。该函数采用以下原子之一:

     
      
  • :impls-如果已合并,则返回{:consolidated, modules}以及实现该协议的模块列表,否则返回:not_consolidated

  •   
  • [...]

  •   

示例:

iex> String.Chars.__protocol__(:impls)
# => {:consolidated, [Postgrex.Copy, Postgrex.Query, Decimal, Float, DateTime, Time, List, Version.Requirement, Atom, Integer, Version, Date, BitString, NaiveDateTime, URI]}