在Elixir中执行某些交叉问题的方式是什么?假设我想检查用户是否取消订阅电子邮件 - 是否可以在执行任何电子邮件发送功能之前执行此操作?在Elixir文档中找不到任何关于交错其他函数的内容......就像在rails中的before_filter但在独立的Elixir应用程序中一样。可能会发送多封电子邮件 - 通知,营销,交易等。添加每个未订阅的电子邮件?手动检查每个功能是非常必要的。 Elixir有更好的方法吗?
答案 0 :(得分:0)
在Rails中,使用before_filter
实际上会导致糟糕的设计。我知道以这种方式编写代码会更容易,但过了一段时间,代码库会增长,你会在这些回调中添加更多逻辑,然后开始放松对它们的控制。
你可以在没有回调的情况下做同样的事情,使用简单的函数,并以命令的方式保持控制(更容易推理和调试)。
假设您有一个具有多个电子邮件功能的模块
defmodule Mailer do
def send_email1(params) do
# do work
end
def send_email2(params) do
end
# ...
end
您可以简单地将代码添加到每个函数中,而不是添加某种before_filter
吗?这很容易理解发生了什么。
defmodule Mailer do
def send_email1(params) do
if can_send?(params) do
# do work
end
end
# ...
end
现在你注意到你有重复的逻辑。那么......您可以将检查逻辑移动到更新的功能,并至少从每个功能中删除if
。但是你也可以创建一个新的抽象并保持共享逻辑。
defmodule Mailer do
def send_email(email_name, params) do
if can_send?(params) do
do_send_email(email_name, params)
end
end
defp do_send_email("email1", params) do
# do work
end
# ...
end
这比使用回调的任何替代方法更简单。你可以控制它。如果需要,可以轻松添加或更改共享逻辑,并为其添加条件逻辑。
答案 1 :(得分:0)
我喜欢使用Elixir的module attributes来启动一系列尾调优化函数调用。这样可以很容易地在一个地方声明回调。
defmodule MyMod do
@before_filter [:check_email]
def check_email(1), do: true
def check_email(state), do: false
def save(state) do
save(state, @before_filter)
end
defp save(state, []) do
# do actual save
{:ok, state}
end
defp save(state, [callback|tail]) do
if :erlang.apply(__MODULE__, callback, [state]) do
save(state, tail)
else
{:error, callback, state}
end
end
end