Protocols are a mechanism to achieve polymorphism in Elixir.
Dispatching on a protocol is available to any data type as long as it
implements the protocol. Lets look at an example of using protocols. We
used a function called to_string in the previous chapters to
convert from other types to the string type.
This is actually a protocol. It can take as input the thing you give it and act according to that without producing an error. This might sound a little like pattern matching functions, but as you'll see now, it is quite different. Lets have a look at a practical example.
Let us create a protocol that'll give us if the given input is empty or not. We'll call this protocol blank?.
So this Protocol is saying that anything that implements it must have an empty? function, although it is up to the implementor as to how the function responds. With the protocol defined, lets take a look at adding a couple of implementations.
This is actually a protocol. It can take as input the thing you give it and act according to that without producing an error. This might sound a little like pattern matching functions, but as you'll see now, it is quite different. Lets have a look at a practical example.
Let us create a protocol that'll give us if the given input is empty or not. We'll call this protocol blank?.
Defining a protocol
We can define a protocol in elixir in the following way:defprotocol Blank do def blank?(data) endAs you can see, we don’t need to define a body for the function. If you are familiar with interfaces in other programming languages, you can think of a Protocol as essentially the same thing.
So this Protocol is saying that anything that implements it must have an empty? function, although it is up to the implementor as to how the function responds. With the protocol defined, lets take a look at adding a couple of implementations.
Implementing a protocol
Since we have defined a protocol, we now need to tell it how to handle the different inputs that it might get. Let us build on the example we had taken earlier. We will implement the blank protocol for lists, maps and strings. This will tell us if the thing we passed is blank or not.#Defining the protocol defprotocol Blank do def blank?(data) end #Implementing the protocol for lists defimpl Blank, for: List do def blank?([]), do: true def blank?(_), do: false end #Implementing the protocol for strings defimpl Blank, for: BitString do def blank?(""), do: true def blank?(_), do: false end #Implementing the protocol for maps defimpl Blank, for: Map do def blank?(map), do: map_size(map) == 0 end IO.puts(Blank.blank? []) IO.puts(Blank.blank? [:true, "Hello"]) IO.puts(Blank.blank? "") IO.puts(Blank.blank? "Hi")You can implement your Protocol for as many or as few types as you want, whatever makes sense for the usage of your Protocol. This was a pretty basic use case of protocols. When running above program, it produces following result:
true false true falseNote: If you use this for any types other than those you defined the protocol for it'll produce an error.
No comments:
Post a Comment