Инъекция кода времени компиляции эликсира / AOP

Ранее я использовал код в стиле AOP, чтобы отделить Logic от Logging, и был очень доволен результатами. Я признаю, что мнения об АОП различны, но я бы хотел найти решение в Elixir, даже если бы я не использовал его в продуктах.

Самый близкий пример, который я видел, - это обратный вызов установки внутри ExUnit, который позволяет выполнять код перед каждым тестом; Я хотел бы сделать что-то подобное, но не смог запутаться в источнике ExUnit, чтобы понять там интуицию.

В кодовой форме:

defmodule Project.Logic do
    LoggingInjection.inject Project.Logging

    def work_do_stuff(arg) do
        #...
        #returns some_result
    end
end

в отдельном файле кода:

defmodule Project.Logging do
    #called just before Project.Logic.work_do_stuff with the same args
    def before_work_do_stuff(arg) do
        Log.write("about to work_do_stuff with #{inspect arg}")
    end
    # def after_work_do_stuff(some_result) implicitly defined as no-op,
    # but could be overridden.
end

и, наконец, реальный вопрос: что это за код, чтобы включить эту магию?

defmodule LoggingInjection do
    defmacro inject(logging_module) do
        #What goes here?
    end
end

Ответы на вопрос(4)

Ваш ответ на вопрос