Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Struct reuse for Modules in Elixir

Tags:

elixir

What mechanisms are there to achieve struct reuse: define a struct with all the fields of another struct plus some of its own.

I have these structs that sort of look like this

defmodule VideoView do
  defstruct name: nil, description: nil, video_link: nil, ...
end

defmodule ImagesView do
  defstruct name: nil, description: nil, images: [], ...
end

defmodule Model3DView do
  defstruct name: nil, description: nil, model: nil, ...
end

There are 7 of these. In my UML they all inherit from View which has name and description. I'd like all of them to share these common fields, especially if I decide to add or remove a common field, this could be a real pain with the current method.

like image 234
Cristian Garcia Avatar asked Sep 29 '15 15:09

Cristian Garcia


People also ask

What is a struct in Elixir?

Structs are extensions built on top of maps that provide compile-time checks and default values.

What is __ module __ In Elixir?

__MODULE__ is a compilation environment macros which is the current module name as an atom. Now you know alias __MODULE__ just defines an alias for our Elixir module. This is very useful when used with defstruct which we will talk about next.

What are module attributes Elixir?

Module attributes in Elixir serve three purposes: They serve to annotate the module, often with information to be used by the user or the VM . They work as constants. They work as a temporary module storage to be used during compilation.


1 Answers

As others have suggested, you should really think twice whether you really gain that much from re-using structs.

If you still need it to reduce massive duplication, you can use module attributes to initially store the struct options. Then you can re-use them with defstruct and expose them for other modules through a function:

defmodule View do
  @common_fields [name: nil, description: nil]
  def common_fields, do: @common_fields
  defstruct @common_fields
end

If you do not plan on using View on its own, you can just put the common fields in a function directly:

defmodule View do
  def common_fields do
    [name: nil, description: nil]
  end
end

Then, you can use the common fields in your other structs like this:

defmodule VideoView do
  defstruct View.common_fields ++ [video_link: nil, ...]
end

defmodule ImagesView do
  defstruct View.common_fields ++ [images: [], ...]
end

defmodule Model3DView do
  defstruct View.common_fields ++ [model: nil, ...]
end
like image 109
Patrick Oscity Avatar answered Sep 18 '22 13:09

Patrick Oscity