Define a function at compile-time

I managed to make it work using both your advices. In fact I thought you had given two different ways of doing things but it looks like we have to combine them.

defmodule Rules do
  Module.register_attribute(__MODULE__, :rule_ids, accumulate: true, persist: false)

  @on_definition {Hooks, :rule_ids}
  @before_compile {Hooks, :create_rule_ids}

# ...
end
defmodule Hooks do
  def rule_ids(_env, :def, :condition, [rule_id | _], _guards, _body)
  when is_integer(rule_id)
  do
    Module.put_attribute(Rules, :rule_ids, rule_id)
  end
  def rule_ids(_env, _kind, _name, _args, _guards, _body), do: nil

  defmacro create_rule_ids(_env) do
    quote do
      def rule_ids, do: unquote(Module.get_attribute(Rules, :rule_ids))
    end
  end
end