Elixir:如何为仅导入大量函数的模块添加别名

时间:2017-11-20 16:21:03

标签: elixir phoenix-framework

我想将我的Accounts上下文函数放入他们自己的文件中,然后将它们导入上下文,以便我可以在控制器中为App.Accounts设置别名,并使用导入上下文的函数。

请参阅下文,了解我所追求的粗略设置。

defmodule App.Accounts.UserAPI do
  alias App.Accounts.User

  def get_user!(id), do: User.get!(User, id) end

  defmacro __using__(_) do
    import App.Accounts.UserAPI
end

defmodule App.Accounts do
  alias App.Accounts.UserAPI
  use UserAPI
end

defmodule AppWeb.UserController do
  alias App.Accounts

  IO.inspect Accounts.module_info
  # [
    # module: Ev2.Accounts, 
    # exports: [__info__: 1, module_info: 0, module_info: 1],
    # attributes: [vsn: [234644860605005629180170678994286615550]],
    # compile: [options: [:debug_info], version: '7.0.4',
    # source: '/Users/.../accounts.ex'],
    # native: false,
    # md5: <<176, 134, 244, 210, 70, 244, 89, 41, 130, 7, 134, 109, 55, 131, 27, 254>>
  # ]
  def index(conn, %{"id" => id}) do
    Accounts.get_user(id) # Accounts.get_user/1 is not defined
  end
end

我目前通过将整个App.UserAPI包装在__using__宏和引号中来工作,但这感觉很冗长并且引用包装似乎阻止我从{{1}内调用实用程序函数}。

为什么UserAPI函数没有出现在UserAPI导出中?  什么是&#34;权利&#34;这样做的方法?

谢谢!

1 个答案:

答案 0 :(得分:2)

问题是导入的函数不是由模块导出的。它们仅在导入的上下文中可用。您想要重新导出导入的函数。我有两种方法可以想到。

  1. 根据您的描述您目前正在做什么:在if(!isset($_SESSION["UserID"])){... ... } else { ...// handle the error } 中的报价栏中定义所有功能:

    __using__
  2. 使用defmodule App.Accounts.UserAPI do defmacro __using__(_) do quote do alias App.Accounts.User def get_user!(id), do: User.get!(User, id) end end end end 定义一个只调用另一个函数的函数:

    defdelegate
  3. 在这两种情况下,defmodule App.Accounts.UserAPI do def get_user!(id), do: User.get!(User, id) end defmacro __using__(_) do quote do defdelegate :get_user!(id), to: App.Accounts.UserAPI end end end 都会做你想要的。