Fl4m3Ph03n1x
How to use anonymous functions in configuration files?
Background
I have a configuration file called test.exs that does not work because it has an anonymous function:
# stub for fire function
config :my_aop,
fire: fn(_pool_name, _endpoint) -> {:ok, :received} end
And it generates the following error:
** (ArgumentError) cannot inject attribute @default into function/macro because cannot escape #Function<12.128620087/2 in :erl_eval.expr/5>. The supported values are: lists, tuples, maps, atoms, numbers, bitstrings, PIDs and remote functions in the format &Mod.fun/arity
(elixir) lib/kernel.ex:2879: Kernel.do_at/5
(elixir) expanding macro: Kernel.@/1
lib/bidtor/dispatcher.ex:36: Bidtor.Dispatcher.send/2
(elixir) lib/kernel/parallel_compiler.ex:208: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/6
Questions
- Can I not use anonymous functions in config files? (Is there a way this can be achieved or is it simply impossible?)
- How can I stub the given function if I cannot use anonymous functions in the configuration files?
Marked As Solved
stefanluptak
AFAIK it’s not possible to store anonymous functions in the config file, but I was not able to find more info quickly.
But it’s solvable. Put the logic into a module. Then put your “testing” logic into another module. Then just use the config to determine which module you want to use.
defmodule YourModule do
def your_function(pool_name, endpoint) do
# some real logic
end
end
defmodule YourModuleMock do
def your_function(_pool_name, _endpoint) do
{:ok, :received}
end
end
test.exs:
config :my_aop, fire: YourModuleMock
usage:
module = Application.get_env(:my_aop, :fire, YourModule)
module.your_function(param1, param2)
Also Liked
peerreynders
You may also want to borrow this from a typical Phoenix project.
In mix.exs:
def project do
[
app: :form_demo,
version: "0.1.0",
elixir: "~> 1.5",
elixirc_paths: elixirc_paths(Mix.env()),
compilers: [:phoenix, :gettext] ++ Mix.compilers(),
start_permanent: Mix.env() == :prod,
deps: deps()
]
end
]
In particular elixirc_paths. The elixirc_paths/1 function returns the compilation paths based on the mix environment. Further down:
# Specifies which paths to compile per environment.
defp elixirc_paths(:test), do: ["lib", "test/support"]
defp elixirc_paths(_), do: ["lib"]
So for :test test/support is added to the compilation path. So all .ex files only used for testing go under test/support and those modules are then available for all the .exs testing scripts.
In combination with values set in config.exs and compile time use of Application.fetch_env!/2 the appropriate module can then be selected (example).
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









