elixir - 如何在一个模块 Elixir 中获取所有重复的 genserver 调用
问题描述
我创建了 2 个 genservers。
camera.ex
defmodule Camera do
use GenServer
defmodule Attributes do
defstruct ~w|name url password port username id owner_id status|a
end
def start_link(state \\ %Attributes{} ) do
GenServer.start_link(__MODULE__, %Attributes{state | id: make_ref()})
end
def init(state) do
{:ok, state}
end
def details(pid) do
GenServer.call(pid, :get)
end
def update(pid, map) do
GenServer.cast(pid, {:update, map})
end
def handle_call(:get, _from, state) do
{:reply, state, state}
end
def handle_cast({:update, map}, state) do
{:noreply, Map.merge(map, state)}
end
end
我有相同的 Genserver,因为user.ex
两者之间的唯一区别是属性。
在相机中
defmodule Attributes do
defstruct ~w|name url password port username id owner_id status|a
end
在用户中
defmodule Attributes do
defstruct ~w|id username|a
end
并且所有其他调用都是重复的,我正在保存用户/相机或更新用户或相机。
我如何制作可以在用户和相机中使用的通用模块,它将采用该模块的行为,这将有助于减少重复。谢谢你。
解决方案
有两种不同的做法:一种是使用defdelegate/2
代码复制代替。
另一种是使用元编程。
defmodule Scaffold do
@moduledoc false
defmacro __using__(opts) do
quote generated: true, location: :keep do
use GenServer
defmodule Attributes, do: defstruct unquote(opts)
def start_link(state \\ %Attributes{}) do
GenServer.start_link(__MODULE__,
%Attributes{state | id: make_ref()})
end
def init(state), do: {:ok, state}
def details(pid),
do: GenServer.call(pid, :get)
def update(pid, map),
do: GenServer.cast(pid, {:update, map})
def handle_call(:get, _from, state),
do: {:reply, state, state}
def handle_cast({:update, map}, state),
do: {:noreply, Map.merge(map, state)}
end
end
end
并将其用作
defmodule Camera do
use Scaffold, [:name, :url, ...]
end
推荐阅读
- javascript - 不区分大小写的单词Javascript的正则表达式
- java - Android Firebase:如何从对象内部获取对象列表
- java - 制作接受姓名、时间、工资率的并行数组
- python - 函数中的 NameError (python 3.6)
- python - GroupBy 并将元素与 Python 中的组的分位数进行比较
- php - 显示 symfony 表单
- android - Android 内部共享存储中的 Xamarin SqlLite 数据库
- php - 使用 AJAX 更改面板标题文本
- matlab - Matlab 存储/修改对矩阵内变量的引用
- google-chrome - 如何匿名使用 chrome/chromium 并同时登录谷歌