Advertisement
Guest User

Untitled

a guest
May 28th, 2015
262
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.34 KB | None | 0 0
  1. # Just an example of specialization in Elixir.
  2. #
  3. # I'm not sure if this pattern is a good practice in Elixir or
  4. # it's too much "OOP-like" and it would be more Elixirific to
  5. # use protocols. But using protocols to do the same thing would
  6. # probably lead to more boilerplate code (explicitly define all
  7. # funX in every protocol implementation).
  8. #
  9.  
  10.  
  11. # general base module
  12. defmodule ImplBase.State do
  13. defstruct base_data: nil
  14. end
  15.  
  16. defmodule ImplBase do
  17. alias ImplBase.State
  18.  
  19. defmacro __using__([]) do
  20. quote do
  21. def fun1(state) do
  22. #
  23. # NOTE: this is problematic - we DEMAND that all implementations' state data
  24. # allow Acces.get(data,:base_data)
  25. #
  26. # Or we could use some custom protocol to access base_data here but it's
  27. # almost the same situation...
  28. #
  29. IO.puts "fun1 - ImplBase implementation. data=#{inspect state.base_data}"
  30. state
  31. end
  32. def fun2(state) do
  33. IO.puts "fun2 - ImplBase implementation. data=#{inspect state.base_data}"
  34. state
  35. end
  36. defoverridable [fun1: 1, fun2: 1]
  37. end
  38. end
  39.  
  40. @doc "Initialize ImplBase data"
  41. def init do
  42. %State{base_data: :some_base_data}
  43. end
  44. end
  45.  
  46. # specific module no 1
  47. # - implementation without using any processes
  48. defmodule Impl1.State do
  49. defstruct base_data: nil, impl1_data: nil
  50. end
  51.  
  52. defmodule Impl1 do
  53. alias Impl1.State
  54. use ImplBase
  55.  
  56. @doc "Initialize Impl1 data"
  57. def init do
  58. %State{base_data: ImplBase.init, impl1_data: :some_impl1_data}
  59. end
  60.  
  61. def fun1(s=%State{}) do
  62. IO.puts "fun1 - Impl1. data=#{inspect s}"
  63. s
  64. end
  65. end
  66.  
  67. # specific module no 2
  68. # - implementation using Agent to store data
  69. #
  70. # NOTE: we have little problem here - we must use one data structure
  71. # as state wich allows Access.get(s,:base_data) and another
  72. # datastructure to be fed into Agent...
  73. defmodule Impl2.State do
  74. defstruct impl2_data: nil
  75. end
  76.  
  77. defmodule Impl2 do
  78. alias Impl2.State
  79. use ImplBase
  80.  
  81. @doc "Initialize Impl2 data"
  82. def init do
  83. {:ok,a} = Agent.start_link fn -> %State{impl2_data: :some_impl2_data} end
  84. %{base_data: ImplBase.init, agent: a}
  85. end
  86.  
  87. def fun1(s=%{agent: a}) do
  88. data = Agent.get a, fn x -> x end
  89. IO.puts "fun1 - Impl2. data=#{inspect data}"
  90. s
  91. end
  92. end
  93.  
  94. #
  95. # main
  96. #
  97.  
  98. Impl1.init
  99. |> Impl1.fun1
  100. |> Impl1.fun2
  101.  
  102. Impl2.init
  103. |> Impl2.fun1
  104. |> Impl2.fun2
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement