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

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
peck
Hi everyone. My team and I have been working on a fairly modest app based around video streaming and chat, but we’ve landed a customer t...
New
achenet
Hello, I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind. However, when I launch mix phx.server, I get an error...
New
bradley
I really like the adapter patterns that ecto, nebulex, waffle, etc. use and would love find something similar for a key management servic...
New
unaware8150
Hello folks! So at work, we are seeing some situations where we have to define some “fixed” strings that are used across the codebase in...
New
Alvinkariuki
How Can I Optimise Compile Time Dependencies I have been building an elixir application for about 2 years now. Many modules and files ha...
New

Other Trending Topics Top

budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New
KristerV
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
mudasobwa
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
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
juhalehtonen
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New
budgie
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with. But I don’t use it anymore. Serverless was the promis...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews