kalkatfyodor

kalkatfyodor

Do I have to write @impl true before each function?

I am watching this video https://youtu.be/_rTFZbvMfJA?t=1252 and the presenter is saying that putting @impl true offers some better error handling - but doesn’t go deeper. In other tutorials like this one https://youtu.be/x1rx4-AAcMQ?t=346 where they don’t put @impl true before mount, render and handle functions.

Should I put @impl true before each function in Phoenix or not?

First Post!

tomkonidas

tomkonidas

That is because he is implementing a Behaviour.

No, you do not need it for every function. But if you put on one function in the module,
then it will complain to put on the others.

Most Liked

sodapopcan

sodapopcan

I have a feeling you are brand new to this language (apologies if I’m wrong) and perhaps these answers are overcomplicating things (no disrespect to anyone trying to help here!)

The short answer is that you can choose to annotate your callback implementations (in the case of LiveView: render/1, mount/3, handle_event/3, etc) with @impl true. Without worrying about anything else, the absolute simplest thing this accomplishes is letting anyone reading the file know that these are callbacks. While it is optional, I highly recommend it.

@tomkonidas provided a very good explanation of behaviours (which you are now well aware is what @impl true is tied to) but my one-line definition is: “a set of functions a module must implement”. As a starting point, you can think of behaviours like interfaces from OO even though it’s not strictly true.

Also, when defining multiple versions of the same function, you only need to annotate the first one:

@impl true
def handle_event("update_post", params, socket) do
  {:noreply, socket}
end

# not required here!
def handle_event("delete_post", params, socket) do
  {:noreply, socket}
end
tomkonidas

tomkonidas

So you can define a behaviour and implement it. For example, lets use payment provider.

If we know we will have multiple payment providers (ex: Stripe, Paypal, etc…), we might want a behaviour for payment providers. We can do this with a behaviour.
We can define the behaviour and say that every module that implements the MyApp.PaymentProvider behaviour needs to implement a credit/2 and debit/2 for example.

Now in our own Stripe module we can @behaviour MyApp.PaymentProvider and that is saying that we will need to implement the 2 callbacks we defined:

  • debit/2
  • credit/2

Now we have a way to make sure we are able to switch between Paypal and Stripe because they follow the same contract. Both Paypal.credit/2 and Stripe.credit/2 should take the same args and return the same type/structure.

With Phoenix, they have optional callbacks, You can define your own or use the default. That is why you do not need to implement Phoenix.LiveComponent.update/2, but you can impl it if you want.

In your module, if you put one @impl over a function, I believe the compiler will complain. Because you iplemented it for another callback but not that specific one, so it thinks you made a possible mistake.

11
Post #5
gabriel137

gabriel137

This feature informs the terminal which functions are returned from a call like in GenServer. You don’t need to include them at all, just the first one.

To learn more, view the link below, I recommend that you first understand what GenServers are.

https://elixircasts.io/%40impl-attribute

Last Post!

whathappenedtoicabod

whathappenedtoicabod

This is all I’ve ever came across about it @impl true

Where Next?

Popular in Questions Top

electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
New
lessless
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

Other popular topics Top

JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 54996 245
New
sergio_101
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
AstonJ
Posting this to see if we can make things easier for people to get into Neovim. If you use Neovim and have a favourite distro please let ...
New

We're in Beta

About us Mission Statement