Question

My blank.ex is :

defprotocol Blank do
  @fallback_to_any true
  def blank?(data)
end

defimpl Blank, for: Any do
  def blank?(_), do: false
end

and I type in iex, the output is:

iex(18)> Blank.blank? []
true
iex(19)> Blank.blank? [6]
false
iex(20)> Blank.blank? '12'
false
iex(22)> Blank.blank? "' "
true
iex(23)> Blank.blank? "elixi"
true
iex(24)> Blank.blank? {1}
true
iex(25)> Blank.blank? {1, 2}
true
iex(26)> Blank.blank? 2
false

So I'm wondering what does the Any means in this context? and I got something interesting, weather or not I use the implemented like this

defimpl Blank, for: Any do
  def blank?(_), do: false
end

and the output in the iex before it's the same. Does that means this implemented does nothing? Or I have missed something?

Was it helpful?

Solution

Any clause should be called if an implementation is not provided.

I don't know why you're getting these weird results, but I suspect you have some incorrect definitions in the shell session. I have tried with the example from the site:

defprotocol Blank do
  @fallback_to_any true
  def blank?(data)
end

defimpl Blank, for: Integer do
  def blank?(_), do: false
end

# Just empty list is blank
defimpl Blank, for: List do
  def blank?([]), do: true
  def blank?(_),  do: false
end

# Just the atoms false and nil are blank
defimpl Blank, for: Atom do
  def blank?(false), do: true
  def blank?(nil),   do: true
  def blank?(_),     do: false
end

defimpl Blank, for: Any do
  def blank?(_), do: false
end

And got expected results:

iex(1)> Blank.blank? "' "
false

iex(2)> Blank.blank? "elixi"
false

iex(3)> Blank.blank? []
true

iex(4)> Blank.blank? {}  # fallback to Any
false

The last example is a fallback to Any, since the protocol is not defined for a tuple. If you remove the Any implementation, and restart the shell, you should get an error:

iex(1)> Blank.blank? {}
** (Protocol.UndefinedError) protocol Blank not implemented for {}

OTHER TIPS

I know what's my confusing. I also get started with example this site. Firstly my blank.ex is

defprotocol Blank do
  def blank?(data)
end

defimpl Blank, for: Integer do
  def blank?(_), do: false
end

defimpl Blank, for: List do
  def blank?([]), do: true
  def blank?(_), do: false
end

and after I compile it elixirc blank.ex, it will create these beam files:

Elixir.Blank.Integer.beam   Elixir.Blank.List.beam   Elixir.Blank.beam

and secondly my blank.ex is

defprotocol Blank do
  @fallback_to_any true
  def blank?(data)
end

defimpl Blank, for: Any do
  def blank?(_), do: true
end

and I compile it again, I got these beam files:

Elixir.Blank.Any.beam  Elixir.Blank.Integer.beam Elixir.Blank.List.beam Elixir.Blank.beam

It doesn't delete the Elixir.Blank.Integer.beam Elixir.Blank.List.beam files, and when I run in iex:

iex(18)> Blank.blank? [] # it uses Elixir.Blank.List.beam
true
iex(19)> Blank.blank? [6] # it uses Elixir.Blank.List.beam
false
iex(20)> Blank.blank? '12' # it uses Elixir.Blank.List.beam
false
iex(22)> Blank.blank? "' " # it uses Elixir.Blank.Any.beam
true
iex(23)> Blank.blank? "elixi" # it uses Elixir.Any.List.beam
true
iex(24)> Blank.blank? {1} # it uses Elixir.Blank.Any.beam
true
iex(25)> Blank.blank? {1, 2} # it uses Elixir.Blank.Any.beam
true
iex(26)> Blank.blank? 2 # it uses Elixir.Blank.Integer.beam
false

So this is just because my missing of deleting the older beam files manually.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top