Any ideas how to perform module middleware? Like Plug do but for modules.
Example:
defmodule ModuleA do
use Magic, only [:target_fun]
def target_fun(someparams) do
end
def no_magic_here(params) do
end
end
defmodule ModuleB do
def calling_fun do
result = ModuleA.target_fun(someparams)
end
end
defmodule Magic do
defmacro __using__(_) do
quote do
def run_me_before_some_functions() do
do_some_job
result = apply(__MODULE__, target_fun, someparams)
do_some_job
result
end
def do_some_job do
end
end
end
@DmytroNasyrov: You could make it with module attributes and your custom def macro, but it’s not easy to do and it’s not clear. Easier way is to write something like:
defmodule Hello do
def world, do: IO.puts "Hello world!"
end
defmodule Jobs do
def first_job do
# ...
end
end
defmodule Magic do
def call(module, method, args, opts \\ %{}) do
if Map.has_key?(opts, :before), do: do_call(opts.before)
apply(module, method, args)
if Map.has_key?(opts, :after), do: do_call(opts.before)
end
defp do_call({module, method, args}) do
apply(module, method, args)
end
end
tuple = {Jobs, :first_job, []}
Magic.call(Hello, :world, [], %{after: tuple, before: tuple})
Yes, my solution is very-very similar to this. Just instead of Magic.call(m, :f, a) it’s Jobs.run(:f, [a]).
But I want to completely hide that and make it Jobs.f(a)