Gigitsu

Gigitsu

Summary

I’m trying to create a macro that takes in input a module name and automatically creates a defdelegate for each function defined in that module.

Example

defmodule MyApp.TargetModule1 do
  def foo(name, opts \\ []) do
    name <> to_string(opts)
  end

  def bar(name) do
    String.uppercase(name)
  end
end

defmodule MyApp.TargetModule2 do
  def baz(name) do
    "Ciao" <> name
  end
end


defmodule MyApp.DelegateModule do
  delegate_all MyApp.TargetModule1
  # the line above will generate the following:
  # defdelegate foo(name, opts \\ []), to: MyApp.TargetModule1
  # defdelegate bar(name), to: MyApp.TargetModule1

  delegate_all MyApp.TargetModule2
  # the line above will generate the following:
  # defdelegate baz(name), to: MyApp.TargetModule2
end

What I’ve done so far

I achieved this using Code.fetch_docs/1 and Code.Typespec.fetch_specs/1 but unfortunately these functions won’t work unless the .beam file isn’t already written on disk so when I modify any target module I get the :module_not_found error.

I know I can get the function list with MyApp.TargetModule1.__info__(:functions) but this will return a simple list of functions and arities without arguments names and possibly default arguments.

Questions

I already looked into ExUnit.DocTest but it also uses Code.fetch_docs/1 and I don’t know how does it work! Tests are compiled after the main lib files?

How can I get function signature (possibly also specs and documentations) from a module at runtime?

Showing Posts 1 to 5

LostKobrakai

LostKobrakai

The macro does include a require Module into the testcase, which makes the compiler enforce that Module is compiled before the file/module having the require Module.

Gigitsu

Gigitsu OP

I also include a require Module and indeed when I call Code.ensure_loaded/1 I get an {:ok, module} response but nevertheless if I call Code.fetch_docs/1 right after the requrie and ``Code.ensure_loaded/1 I get amodule_not_found` error.

Gigitsu

Gigitsu OP

This is my prototype

quote do
  require unquote(target)
  {:module, target} = Code.ensure_loaded(unquote(target)) # -> {:module, target}
  {_, _, _, _, _, _, functions} = Code.fetch_docs(target) # -> {:error, :module_not_found}
end
hauleth

hauleth

That doesn’t matter, as Erlang do not have notion of “default arguments” so what Elixir does to support them is to simply create multiple functions:

def foo(a, b \\ 1), do: …

Is the same as:

def foo(a), do: foo(a, 1)

def foo(a, b), do: …

Yes, exactly that.


AFAIK there is no way to fetch docs for in-memory module unless you store generated BEAM data in variable.

The only feasible approach is to use mod.__info__(:functions) (or mod.module_info(:functions) if you are willing to do filtering on your own).

Gigitsu

Gigitsu OP

With mod.__info__(:functions) and mod.module_info(:functions) I can’t know parameters name and which parameter ha a default.

My current work around, since I’m working on an umbrella project, is to put every delegate module in a separate app. In my specific case this workaround should work, but I was hoping in a more reliable solution.

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
apz
I’m new to elixir and just tried to install the elixirLS extension for VScode(ium) and it is throwing some errors that I would like help ...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews