Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to find all modules that implement certain protocol?

I was wondering whether is it possible to find all modules that have implementations for certain module?

I have a simple protocol:

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

And few modules that have implementations of this protocol:

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
like image 980
Haito Avatar asked Mar 01 '16 15:03

Haito


2 Answers

Protocol.extract_impls/2 appears to be what you're looking for.

Extracts all types implemented for the given protocol from the given paths.

Thanks to OP's comment, here's what the code should look like for the example in the question:

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

Since we're calling the Erlang :code module here to get the path, the module name needs to be in the atom format Erlang uses.

like image 131
CoderDennis Avatar answered Oct 13 '22 15:10

CoderDennis


You're looking for the __protocol__/1 method. From the docs:

__protocol__/1 - returns the protocol information. The function takes one of the following atoms:

  • :impls - if consolidated, returns {:consolidated, modules} with the list of modules implementing the protocol, otherwise :not_consolidated

  • [...]


Example:

iex> String.Chars.__protocol__(:impls)
# => {:consolidated, [Postgrex.Copy, Postgrex.Query, Decimal, Float, DateTime, Time, List, Version.Requirement, Atom, Integer, Version, Date, BitString, NaiveDateTime, URI]}
like image 24
Sheharyar Avatar answered Oct 13 '22 14:10

Sheharyar