在 Elixir config 中使用 ENV 的一点技巧

看到了 Erlang Solution 的这篇文章,想到了这个话题。这篇文章虽然内容不多,但还是挺有用的。文中提到的编译时和运行时的区别,也是刚学 Elixir 搞不太清的问题。

而 Elixir 的 config 也并不是简单的启动前执行的代码,特别是在部署时。

有时我们可能会想在 config 里使用 ENV,比如:

config :my_app, api_key: System.get_env("API_KEY")

但直接这样写到 config 中是不行的。在部署时,比如通过 distillery 运行 mix release ,config 就会变成 sys.config,System.get_env(“API_KEY”) 已经被计算了,等运行的时候就不能动态得到 ENV 的实际值了。

有种做法就是像上边那篇文章中最后提到的方式,把 ENV 的获取逻辑放到函数里去做,这样就变成了运行时才会执行了:

# config.exs
config :my_app, api_key: {:env, "API_KEY"}

# my_app.ex
def api_key do
  get_env(Application.get_env(:my_app, :api_key))
end

def get_env({:env, key}), do: System.get_env(key)

Phoenix 的 config 支持从 ENV 中获取 port 就是这样处理的:

# https://github.com/phoenixframework/phoenix/blob/996a83a27d8ccdc7e0e3bdda9c21d537b19b2002/installer/templates/new/config/prod.exs#L15
config :<%= app_name %>, <%= app_module %>.Endpoint,
  http: [:inet6, port: {:system, "PORT"}]

 # https://github.com/phoenixframework/phoenix/blob/2295ba7440221871b64c9535dec404c7d53589eb/lib/phoenix/endpoint/handler.ex#L57
 defp to_port({:system, env_var}), do: to_port(System.get_env(env_var))
 
7
Kudos
 
7
Kudos

Now read this

ActiveRecord 和 Ecto 的比较

ActiveRecord 是 Ruby on Rails 的 Model 层,是一个 ORM(Object-relational mapping)。Ecto 是 Elixir 实现的一个库,类似于 ORM。不管是不是 ORM,二者本质上都是在各自的语言层面,对于数据库操作提供了抽象,能让我们更方便地和数据库交互,而不是直接通过 SQL 的方式,并且对表中的数据做了映射,从而方便进行后续逻辑的处理。 这篇文章并不打算来争个孰优孰劣,很多时候对比的作用更是加深对于事物的认识... Continue →

Subscribe to Tony Han

Don’t worry; we hate spam with a passion.
You can unsubscribe with one click.

5LlAm7DiB9GD0l5vEcE