@@ -6,7 +6,7 @@ defmodule Protocol do
66 implementations. A protocol is defined with `Kernel.defprotocol/2`
77 and its implementations with `Kernel.defimpl/3`.
88
9- ## A real case
9+ ## Example
1010
1111 In Elixir, we have two nouns for checking how many items there
1212 are in a data structure: `length` and `size`. `length` means the
@@ -102,8 +102,7 @@ defmodule Protocol do
102102 invoking the protocol will raise unless it is configured to
103103 fall back to `Any`. Conveniences for building implementations
104104 on top of existing ones are also available, look at `defstruct/1`
105- for more information about deriving
106- protocols.
105+ for more information about deriving protocols.
107106
108107 ## Fallback to `Any`
109108
@@ -165,6 +164,17 @@ defmodule Protocol do
165164 The `@spec` above expresses that all types allowed to implement the
166165 given protocol are valid argument types for the given function.
167166
167+ ## Configuration
168+
169+ The following module attributes are available to configure a protocol:
170+
171+ * `@fallback_to_any` - when true, enables protocol dispatch to
172+ fallback to any
173+
174+ * `@undefined_impl_description` - a string with additional description
175+ to be used on `Protocol.UndefinedError` when looking up the implementation
176+ fails. This option is only applied if `@fallback_to_any` is not set to true
177+
168178 ## Reflection
169179
170180 Any protocol module contains three extra functions:
@@ -828,7 +838,7 @@ defmodule Protocol do
828838 quote bind_quoted: [ built_in: __built_in__ ( ) ] do
829839 any_impl_for =
830840 if @ fallback_to_any do
831- quote do: unquote ( __MODULE__ . Any )
841+ __MODULE__ . Any
832842 else
833843 nil
834844 end
@@ -874,6 +884,9 @@ defmodule Protocol do
874884 unquote ( any_impl_for )
875885 end
876886
887+ undefined_impl_description =
888+ Module . get_attribute ( __MODULE__ , :undefined_impl_description , "" )
889+
877890 @ doc false
878891 @ spec impl_for! ( term ) :: atom
879892 if any_impl_for do
@@ -882,17 +895,21 @@ defmodule Protocol do
882895 end
883896 else
884897 Kernel . def impl_for! ( data ) do
885- impl_for ( data ) || raise ( Protocol.UndefinedError , protocol: __MODULE__ , value: data )
898+ impl_for ( data ) ||
899+ raise ( Protocol.UndefinedError ,
900+ protocol: __MODULE__ ,
901+ value: data ,
902+ description: unquote ( undefined_impl_description )
903+ )
886904 end
887905 end
888906
889907 # Internal handler for Structs
890908 Kernel . defp struct_impl_for ( struct ) do
891- target =
892- case Code . ensure_compiled ( Module . concat ( __MODULE__ , struct ) ) do
893- { :module , module } -> module
894- { :error , _ } -> unquote ( any_impl_for )
895- end
909+ case Code . ensure_compiled ( Module . concat ( __MODULE__ , struct ) ) do
910+ { :module , module } -> module
911+ { :error , _ } -> unquote ( any_impl_for )
912+ end
896913 end
897914
898915 # Inline struct implementation for performance
0 commit comments