Function sharing in protocol implementations in Elixir

I am just working on a book by Dave Thomas and am currently studying protocols in Elixir. I know that I can return to the general protocol implementation with @fallback_to_any true . For instance:

 defprotocol Caesar do @fallback_to_any true def encrypt(string, shift) def rot13(string) end defimpl Caesar, for: BitString do def encrypt(string, shift) do # implementation for binary end def rot13(string) do # implementation for binary end end defimpl Caesar, for: List do def encrypt(string, shift) do # implementation for character list end def rot13(string) do # implementation for character list end end defimpl Caesar, for: Any do def encrypt(string, shift) do # generic implementation end def rot13(string) do # generic implementation end end 

However, in the above case, basically every implementation of rot13/1 will look like this:

 def rot13(string) do Caesar.encrypt(string, 13) end 

However, I have to repeat this in every implementation, which seems completely wrong. Is there a way to split rot13/1 into all Caesar implementations?

+5
source share
1 answer

So, I found this question about delegation in implementation. This made me wonder if defdelegate inside protocols, and it really is! Thus, the following can be resolved:

 defmodule Caesar.Shared do def rot13(string) do Caesar.encrypt(string, 13) end end defprotocol Caesar do def encrypt(string, shift) defdelegate rot13(string), to: Caesar.Shared end defimpl Caesar, for: BitString do def encrypt(string, shift) do # implementation for binary end end defimpl Caesar, for: List do def encrypt(string, shift) do # implementation for character list end end 

I'm still interested in other answers. Perhaps there is an even better, more idiomatic way to do this directly in the definition of a protocol.

+9
source

Source: https://habr.com/ru/post/1203361/


All Articles