我想以几种(独立的)方式“扩展” Elixir的内置IO /文件功能。
我想出了以下代码模式:
defmodule FileExtension1 do
# arguments are different for different extensions,
# but I guess I could just stick with single map/list
# argument for uniformity
def open!(filename, some_param \\ true) do
filename
|> File.open!
|> attach(some_param)
end
def close(io) do
io |> File.close
end
def attach(io, some_param \\ false) do
spawn_link fn ->
file_manager(io, some_param)
end
end
def detach(io) do
io |> send {:detach, self}
receive do
{:will_detach, ^io} -> :ok
end
end
defp file_manager(io, some_param, state \\ <<>>) do
if Process.alive?(io) do
receive do
{:detach, sender} ->
sender |> send {:will_detach, self}
{:custom_request, sender, reference, count} ->
# {result, new_state} = do_job(...)
sender |> send {:custom_reply, reference, result}
file_manager(io, some_param, new_state)
{:io_request, sender, reference, {:some_pattern}} ->
# {result, new_state} = do_job(...)
sender |> send {:io_reply, reference, result}
file_manager(io, some_param, new_state)
x ->
io |> proxy(x)
file_manager(io, some_param, state)
end
end
end
defp proxy(io, data) do
{request_type, original_from, original_reference, command} = data
reference = make_ref
io |> send {request_type, self, reference, command}
receive do
{response_type, ^reference, result} -> original_from |> send {response_type, original_reference, result}
end
end
end
基本上,它执行以下操作:
File
现在,我可以将这些东西透明地堆叠在一起(即,attach
第一个堆叠到File
,然后第二个堆叠到第一个,依此类推)。
问题是:现在我有三个模块,它们遵循我上面描述的相同模式。我想以某种方式删除代码重复。
我应该看什么?
IO
包含多个设备的共享功能,或Enum
包含几种类型的共享功能。您能否举一个小例子,说明我的情况如何?GenServer
根据自己的需要创建的一些变体中受益。再说一次,如果我应该使用的话,一个小例子会有所帮助。奖励问题:如何使用来测试共享功能ExUnit
?
一个将函数传递给另一个函数的非常简单的示例:
#PassInFunction
defmodule PIF do
def hello(name), do: IO.puts("Hello #{name}!")
def execf(name, f), do: f.(name)
end
PIF.execf("Onorio",&PIF.hello/1)
在您的特定情况下,我将使用文件类型(或扩展名,视情况而定)来确定要传入的函数。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句