tfwright

tfwright

Conditional code based on config

I have a library (MyLib) that I use for part of another app’s functionality (MyApp). I’d like to add some conditional code (an Ecto schema definition) to one of the library’s modules only if MyApp has a particular config that points to one of MyApp’s modules (also an Ecto schema). I was hoping to call a function on the MyApp module to get the info about it I need, but it appears to break compilation in certain circumstances because MyApp hasn’t been compiled yet (I was trying to call __schema__/2 to get info about an association).

One option would be to require the MyApp config specify all the data MyLib needs, but that feels a bit clunky and redundant. Is there a way to force MyApp to compile first so that MyLib can access its module’s functions during compilation time? Or is there another, better way to go about what I’m trying to do?

Appreciate any tips/suggestions.

Marked As Solved

kip

kip

ex_cldr Core Team

Nothing wrong with runtime configuration. But that doesn’t help you if you’re doing meta programming at compile time.

Think of Ecto as a good example. Although all the Repo code lives in Ecto, you are required to create your own MyApp.Repo module and use Ecto.Repo in it with the appropriate configuration. Then the consumer of your code calls the API in MyApp.Repo, not Ecto.Repo. Thats the pattern to follow for your use case I think.

Happy to provide a few pointers on implementing this approach if you get stuck - here or just DM me.

Also Liked

kip

kip

ex_cldr Core Team

You may need to use Code.ensure_compiled/1 to force compilation order if it isn’t being detected the way you want.

The documentation notes that this is not a function you should commonly reach for. However forcing compilation order at compile time is one reasonable use.

kip

kip

ex_cldr Core Team

It would be helpful to know:

  • What the result of Application.get_env(:my_lib, :some_config) is
  • What the error return was (instead of ignoring it add it to the log message)
kip

kip

ex_cldr Core Team

Ah, I see. Compilation order is dependencies first, then the current project. Where current project is the one that has mix.exs in it when you did mix.compile. Dependencies are compiled first and they do not create a transitive association with the “current” project. Understandably so - libraries aren’t built to make assumptions about the projects that use them.

TLDR; A dependency depending on the consumer of the dependency isn’t going to work

kip

kip

ex_cldr Core Team

The common pattern in Elixir to handle this kind of situation is to introduce a new module into the current project and then use the code from the dependency so you can create a relationship. This is what I do heavily in the ex_cldr libs for pretty much the same reason you have - conditional compilation of library code based upon configuration in consumer code.

kip

kip

ex_cldr Core Team

To explain additionally why conditional compilation in a dependency isn’t a good idea I should point out that the dependency could be used my multiple different consuming libraries in the same runtime environment and therefore unpredictable behaviour would ensue.

Where Next?

Popular in Questions Top

senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
New
logicmason
Hi there, I'm working through my first release with elixir/phoenix. I've built a release with distillery and found that it crashes when I...
New
Harrisonl
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service. Currently when I de...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
sabri
Can someone explain the settings of pool_size of Ecto in config file? and what is the recommend size? Thanks
New

Other popular topics Top

JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1140 51847 244
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers' Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
Nvim
Elixir appears to be a superior language to Python. I don’t see any advantage of Python over Elixir. Are there any?
New

We're in Beta

About us Mission Statement