kai_feldhoff

kai_feldhoff

Call callback-function inside Behaviour-Module

In my current project I have a rather complex data-tranfsformation. Additionally there are several flavors fo ths trqansormation that share a lot of behaviour.

Is therea any other may to call a callback-function inside a bahaviour apart from passing the module-name of the callback-module like this?

defmodule MyBehaviour do
  @callback specific_handling(data :: term) :: term

  @callback very_specific_handling(data :: term) :: term

  defmacro __using__(_opts) do
    quote do
      @behaviour MyBehaviour

      alias MyBehaviour

      def initiate_processing(data) do
        MyBehaviour.process_data(data, __MODULE__)
      end
    end
  end

  def process_data(data, callback_module) do
    data
    |> do_stuff_with_data(callback_module)
    # and other calls to behaviour-functions
    |> callback_module.specific_handling()
  end

  defp do_stuff_with_data(data, callback_module) do
    data
    # and other calls to behaviour-functions
    |> do_specific_stuff(callback_module)
  end

  defp do_specific_stuff(data, callback_module) do
    data
    # and other calls to behaviour-functions
    |> callback_module.very_specific_handling()
  end
end

defmodule DataHandler11 do
  use MyBehaviour

  def specific_handling(data) do
    # do specific stuff with data
    data
  end

  def very_specific_handling(data) do
    # do specific stuff with data
    data
  end
end

defmodule DataHandler12 do
  use MyBehaviour

  def specific_handling(data) do
    # do specific stuff with data
    data
  end

  def very_specific_handling(data) do
    # do specific stuff with data
    data
  end
end

data = nil
handler = 1

case handler do
  1 -> DataHandler11.initiate_processing(data)
  2 -> DataHandler12.initiate_processing(data)
end

Marked As Solved

dimitarvp

dimitarvp

I would give you a thumbs up during code review on a PR like this – it’s all good.

If you are worried about this approach then the only other practice that’s more “micro” would be to only pass function references – but then you would be losing the compiler warnings if a contract is violated i.e. if the function has the same arity but accepts different kinds of arguments.

So IMO callback modules are the right solution here.

Where Next?

Popular in Questions Top

bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
makeitrein
Hey all, just started picking up Elixir last week and am writing a scraper as a learning project. Baby step #1 is extracting the number ...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
qwerescape
Is there a way to get the call stack or stack trace at any point in the code? Not from exceptions, but an expression that returns how the...
New
Exadra37
Sometimes I want to check if the input into a function is not a blank string. My first approach: defmodule Example do def do_stuff(s...
New
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> someth...
New
sabri
Can someone explain the settings of pool_size of Ecto in config file? and what is the recommend size? Thanks
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New

Other popular topics Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 record...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 45766 226
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list....
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New

We're in Beta

About us Mission Statement