otuv

otuv

%Struct{} vs %{__struct__: Struct}

Hi,

Lets say I have a struct, lets say named Struct with the singular field x (default 0).

When I create it I get &Struct{x: 0}
Since they are maps I then use Map.put to add something else like y: 5 I get %{struct: S, x: 0, y: 5} and it is no longer an Stuct

Is there some way to purge any non struct fields and restore it to an Struct?

(Here the whole idea is obviously stupid)

Marked As Solved

gregvaughn

gregvaughn

Here’s one approach. I chose the URI struct because it’s small and in the std lib.

iex(39)> u = URI.parse "http://forum.elixirforum.com"
%URI{
  authority: "forum.elixirforum.com",
  fragment: nil,
  host: "forum.elixirforum.com",
  path: nil,
  port: 80,
  query: nil,
  scheme: "http",
  userinfo: nil
}
iex(40)> m = Map.put(u, :y, 5)
%{
  __struct__: URI,
  authority: "forum.elixirforum.com",
  fragment: nil,
  host: "forum.elixirforum.com",
  path: nil,
  port: 80,
  query: nil,
  scheme: "http",
  userinfo: nil,
  y: 5
}
iex(41)> s = struct(m.__struct__, Map.from_struct(m))
%URI{
  authority: "forum.elixirforum.com",
  fragment: nil,
  host: "forum.elixirforum.com",
  path: nil,
  port: 80,
  query: nil,
  scheme: "http",
  userinfo: nil
}

struct/2 ignores keys that are not specified in the struct itself

Also Liked

ityonemo

ityonemo

you can also use map cons, if you would like for your code to crash when you try to assign a nonexistent field, lets you catch errors in tests (how good is your test coverage? lol)

defmodule S do
  defstruct [x: 0]
  def do_something(val = %S{}) do
     %{val | y: "oops"}
  end
end

will crash on do_something. Whenever it’s a struct, I prefer using map cons for that bailout behaviour.

brettbeatty

brettbeatty

I prefer the previous answer, but another option would get a list of keys expected in the struct and take them from the map.

Building on the other example:

iex> Map.take(m, Map.keys(%URI{}))
%URI{
  authority: "forum.elixirforum.com",
  fragment: nil,
  host: "forum.elixirforum.com",
  path: nil,
  port: 80,
  query: nil,
  scheme: "http",
  userinfo: nil
}

Two downsides to this approach compared to the previous:

  1. This solution won’t replace any missing keys.
  2. This approach doesn’t let you create the struct dynamically (not without wrapping it in struct/0 at least, which at that point you might as well do the other).

Where Next?

Popular in Questions Top

Darmani72
If I have a post route which an argument: post /my_post_route/:my_param1, MyController.my_post_handler How would get the post params ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
earth10
Hi, I’m just starting to build a side-project with Elixir and Phoenix and doing some basic test with Elixir alone. What strikes me is th...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lists...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New

Other popular topics Top

skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
baxterw3b
Hi guys, i’m new in the Elixir world, and i have to say, that i love it! i’m having some problem to understand anonymous functions with ...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
AstonJ
Please see the new poll here: Which code editor or IDE do you use? (Poll) (2022 Edition) It’s been a while since we first asked this, I...
208 31142 143
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
marick
I had some trouble figuring out how to make many-to-many associations work. Once I got it working, I wrote a blog post. Because I’m a nov...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

We're in Beta

About us Mission Statement