Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if a Map is also a Struct?

Tags:

elixir

In Elixir I can check if a variable is a map or a struct, by calling Kernel.is_map/1 which makes sense because Structs are Maps underneath, but I'd like to differentiate between the two. I know that I can call __struct__ on a Struct to get it's module name but calling it on a normal map throws:

** (KeyError) key :__struct__ not found in: %{}

So my question is, How do I check if a variable is a map or a struct?


Example use case:

# I want to handle struct and map inputs differently in my Module

defmodule DifferentThings do
  def do_something(arg) when is_map(arg) do
    # Do something with Maps
  end

  def do_something(arg) when is_struct(arg) do
    # But handle Structs differently
    # Issue is, `is_struct` does not exist
  end
end
like image 756
Sheharyar Avatar asked Sep 28 '16 21:09

Sheharyar


2 Answers

In general to check if map is a struct:

Map.has_key?(struct, :__struct__)

For different method declarations (more general method is second):

defmodule DifferentThings do
  def do_something(%{__struct__: _} = arg) do
    # ...
  end

  def do_something(arg) when is_map(arg) do
    # ...
  end
end
like image 135
Alex Avoiants Avatar answered Oct 05 '22 23:10

Alex Avoiants


It is possible to pattern match between struct and map like below

defmodule DifferentThings do
  def do_something(arg = %_x{}) do
    IO.puts "This is a struct"
  end

  def do_something(arg = %{}) do
    IO.puts "This is a map"
  end
end
like image 36
Rajeesh Avatar answered Oct 06 '22 00:10

Rajeesh