Skip to content

Commit ccb8c5a

Browse files
author
José Valim
committed
Add a new anti-pattern section to library guidelines
1 parent 07e580c commit ccb8c5a

File tree

1 file changed

+28
-0
lines changed

1 file changed

+28
-0
lines changed

lib/elixir/pages/Library Guidelines.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,34 @@ The application environment should be reserved only for configurations that are
144144

145145
For all remaining scenarios, libraries should not force their users to use the application environment for configuration. If the user of a library believes that certain parameter should be configured globally, then they can wrap the library functionality with their own application environment configuration.
146146

147+
### Avoid compile-time application configuration
148+
149+
Assuming you need to use the application configuration and you cannot avoid it as explained in the previous section, you should also avoid compile-time application configuration. For example, instead of doing this:
150+
151+
```elixir
152+
@http_client Application.fetch_env!(:my_app, :http_client)
153+
154+
def request(path) do
155+
@http_client.request(path)
156+
end
157+
```
158+
159+
you should do this:
160+
161+
```elixir
162+
def request(path) do
163+
http_client().request(path)
164+
end
165+
166+
defp http_client() do
167+
Application.compile_env!(:my_app, :http_client)
168+
end
169+
```
170+
171+
That's because by reading the application in the module body and storing it in a module attribute, we are effectively reading the configuration at compile-time, which may become an issue when configuring the system later.
172+
173+
If, for some reason, you must read the application environment at compile time, use `Application.compile_env/2`. Read [the "Compile-time environment" section of the Application docs](Application.html#module-compile-time-environment) for more information.
174+
147175
### Avoid `use` when an `import` is enough
148176

149177
A library should not provide `use MyLib` functionality if all `use MyLib` does is to `import`/`alias` the module itself. For example, this is an anti-pattern:

0 commit comments

Comments
 (0)