如何在一个模块 Elixir 中获取所有重复的 genserver 调用
how get all duplicated genserver calls in one module Elixir
我已经创建了 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
我有与 user.ex
相同的 Genserver,两者之间的唯一区别是属性。
在相机里
defmodule Attributes do
defstruct ~w|name url password port username id owner_id status|a
end
并在用户 its
defmodule Attributes do
defstruct ~w|id username|a
end
所有其他调用都是重复的,我正在保存 user/camera 或更新用户或相机。
我如何制作可以在用户和相机中使用的通用模块,它会采用该模块的行为,这将有助于减少重复。谢谢。
有两种不同的方法:一种是使用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
我已经创建了 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
我有与 user.ex
相同的 Genserver,两者之间的唯一区别是属性。
在相机里
defmodule Attributes do
defstruct ~w|name url password port username id owner_id status|a
end
并在用户 its
defmodule Attributes do
defstruct ~w|id username|a
end
所有其他调用都是重复的,我正在保存 user/camera 或更新用户或相机。
我如何制作可以在用户和相机中使用的通用模块,它会采用该模块的行为,这将有助于减少重复。谢谢。
有两种不同的方法:一种是使用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