Re-define and use the 'receive' macro

Hey there,

I am currently experimenting with defining and using my own slightly adjusted receive macro, based on the default. As a classic example, let’s say I want to log every time a Process starts receiving a message from the mailbox. Could I define my own version of the receive macro that does the logging, then calls the default receive macro and import this custom receive into my existing code?

Below is a not-working example to better illustrate what I am trying to achieve:

defmodule MyWeirdReceive do
  def receive(args) do
    IO.puts "I just started receiving a message from the mailbox"
    Kernel.SpecialForms.receive(args)
  end
end


defmodule Stack do
  import Kernel, except: [receive: 1]
  import MyWeirdReceive
  def loop(state, ctr) do
    receive do
      {_from, :push, value} ->
        loop([value | state], ctr + 1)

      {from, :pop} ->
        [h | t] = state
        send(from, {:reply, h})
        loop(t, ctr)
    end

    loop(state, ctr)
  end
end

Unfortunately, receive isn’t a function. It isn’t even a macro - it’s a special form. From the Kernel.SpecialForms module doc:

3 Likes