mguimas

mguimas

What does %Mod{} really do?

Hello,

given the files xx.ex and yy.ex defined as

defmodule XX do
   defstruct [:field]
end
defmodule YY do
  defdelegate __struct__, to: XX
  defdelegate __struct__(x), to: XX
end

why does

iex(1)> %XX{} == XX.__struct__()
true

and

iex(2)> %YY{} == YY.__struct__()
false

give different results?

It seems that %Mod{} is not equivalent to Mod.__struct__()

What does %Mod{} really do?

Thanks
Mário

Most Liked

peerreynders

peerreynders

iex(14)> Map.to_list(%YY{})                
[__struct__: YY, field: nil]
iex(15)> Map.to_list(YY.__struct__())
[__struct__: XX, field: nil]

Kernel.SpecialForms.%/2

Based on the evidence I suspect that the compiled code (it’s a special form after all) sanitizes the value returned from the function by forcing the __struct__ value to reflect the primary module - but that is just a guess.

mguimas

mguimas

This issue has been solved here.

peerreynders

peerreynders

iex(16)> struct!(YY,field: 1)
%XX{field: 1}
iex(17)> struct!(%YY{},field: 1)
%YY{field: 1}

I suspect the bug is with Kernel.struct!/2, not Kernel.SpecialForms.%/2.

https://github.com/elixir-lang/elixir/blob/v1.8.1/lib/elixir/lib/kernel.ex#L2116-L2130

As you discovered, it only presents when you start defdelegating the constructor and I don’t think this code anticipated that.

So the question is - what are you trying to accomplish by defdelegating the struct constructor to another struct? Sharing code between XX and YY should probably be accomplished via a shared third module.

Where Next?

Popular in Questions Top

rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

Other popular topics Top

New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New

We're in Beta

About us Mission Statement