Manuel Albarran

A random notes about Elixir

Polymorphism (Part 2) - Bare Elixir - With Dinamic Module Implementation

18 Feb 2017 » elixir, polymorphism
defmodule Circle do
  defstruct [:r]

  @doc "Calculates the area of a circle"
  def area(%Circle{r: r}), do: :math.pi * r * r
  
  @doc "Calculates the perimeter of a circle"
  def perimeter(%Circle{r: r}), do: 2 * :math.pi * r
end

defmodule Square do
  defstruct [:a]
  
  @doc "Calculates the area of a square"
  def area(%Square{a: a}), do: a * a
  
  @doc "Calculates the perimeter of a square"
  def perimeter(%Square{a: a}), do: 4 * a
end

defmodule Rectangle do
  defstruct [:w, :h]

  @doc "Calculates the area of a polygon"
  def area(%Rectangle{w: w, h: h}), do: w * h

  @doc "Calculates the perimeter of a polygon"
  def perimeter(%Rectangle{w: w, h: h}), do: 2 * w + 2 * h
end


defmodule Polygon do
  def circularity(polygon) do
    area = polygon |> polygon.__struct__.area
    perimeter = polygon |> polygon.__struct__.perimeter 

    (4 * :math.pi * area) / (perimeter * perimeter)
  end
end

%Circle{r: 10} |> Circle.area
#> 304.0592653589793
%Circle{r: 10} |> Polygon.circularity
#> 1.0 # A Perfect Circle

%Square{a: 10} |> Square.area
#> 100
%Square{a: 10} |> Polygon.circularity
#> 0.7853980633974483

%Rectangle{w: 10, h: 5} |> Rectangle.area
#> 50
%Rectangle{w: 10, h: 5} |> Polygon.circularity
#> 0.6981317007977318

[%Circle{r: 10}, %Square{a: 10}, %Rectangle{w: 10, h: 5} ] |> Enum.each(fn polygon ->
  IO.puts polygon |> polygon.__struct__.area
  IO.puts polygon |> polygon.__struct__.perimeter
  IO.puts polygon |> Polygon.circularity
end)
#> 314.1592653589793
#> 62.83185307179586
#> 1.0
#> 100
#> 40
#> 0.7853981633974483
#> 50
#> 30
#> 0.6981317007977318