我正在编写一个Elixir库,其行为很大程度上取决于用户提供的字典文件。我在编译时处理文件,如下所示:
defmodule SomeModule do
@dictionary Application.get_env(:some_lib, :dictionary_file)
|> do_some_processing
...
end
父项目可以指定在config.exs
中使用哪个词典文件:
config :some_lib, dictionary_file: "/path/to/dictionary.txt"
如果父项目的所有者修改了他们的config.exs
以指定其他dictionary_file
,则需要重新编译我的模块。但是,现在,这不仅不会自动发生,如果我在父项目中运行mix deps.compile --force
,它也不会发生。
Elixir提供@external_resource
来表达"如果某个外部文件发生更改,则重新编译我的代码"。但是,如果应用程序环境发生变化,我就没有办法说出"重新编译我的代码"。
我该怎么做?
答案 0 :(得分:1)
我可以这样做:让父应用程序定义一个使用其环境的模块,而不是让我的库模块直接使用环境。他们不会使用LibraryModule.do_stuff()
,而是会调用ParentProjectModule.do_stuff()
。
例如:
defmodule ParentProjectModule do
@dictionary Application.get_env(:some_lib, :dictionary_file)
|> do_some_processing
use LibraryModule
end
然后我可以做:
defmodule LibraryModule
defmacro __using__(_) do
quote do
# define all my functions, using @dictionary as needed
end
end
end
当父应用程序环境发生更改时,将重新编译其模块,因此库函数会相应地运行。