holasoymas
Customer.__struct__/1 is undefined, cannot expand Customer
nested_dict.exs
defmodule Customer do
defstruct name: "", company: ""
end
defmodule BugReport do
defstruct owner: %Customer{}, details: "", severity: 1
end
I got this error after writing this in iex
iex(1)> c "nested_dict.exs"
error: Customer.__struct__/1 is undefined, cannot expand struct Customer. Make sure the struct name is correct. If the struct name exists and is
correct but it still cannot be found, you likely have cyclic module usage in your code
│
4 │ owner: %Customer{name: "Dave", company: "PragProg"},
│ ^
│
└─ nested_dict.exs:4:10
I also try running it using elixir nested_dict.exs got the same error.
I again also run them in through different file:
Customer.exs
defmodule Customer do
defstruct name: "", company: ""
end
nested_dict_api.exs
Code.require_file("Customer.exs")
defmodule BugReport do
defstruct owner: %Customer{}, details: ""
end
nested_dict.exs
Code.require_file("nested_dict_api.exs")
report = %BugReport{
owner: %Customer{name: "Dave", company: "PragProg"},
details: "broken"
}
IO.inspect(report)
Again, the same error ,
I am pretty sure that there are no typo in my code as fas as i know
Can someone please tell me what’s wrong in my code and how to solve it ?
Thank you,
Elixir : 1.17.0 (compiled with Erlang/OTP 27)
OS : Linux Mint 21
Most Liked
Eiji
That’s a scope problem in iex and single file scripts. Since everything is compiled at once (not each file into .beam file inside _build directory) the code must work as custom modules are not defined at compile-time. Using them run-time is definitely not a problem. This behaviour is not best, but very reasonable.
This should do the job:
defmodule Customer do
defstruct name: "", company: ""
end
defmodule BugReport do
defstruct owner: nil, details: "", severity: 1
def new(data \\ %{}, customer \\ nil) do
owner = case customer do
struct when is_struct(struct, Customer) -> struct
map_or_list when is_map(map_or_list) or is_list(map_or_list) -> struct(Customer, map_or_list)
_customer -> %Customer{}
end
map = Map.new(data)
struct(%__MODULE__{owner: owner}, map)
end
end
This allows us to write code like:
iex> BugReport.new()
%BugReport{owner: %Customer{name: "", company: ""}, details: "", severity: 1}
iex> BugReport.new(details: "…")
%BugReport{owner: %Customer{name: "", company: ""}, details: "…", severity: 1}
iex> BugReport.new([], [name: "xyz"])
%BugReport{owner: %Customer{name: "xyz", company: ""}, details: "", severity: 1}
In both cases you are able to use Keyword lists as well as Map and in customer case also Customer struct (of course as long as call with %Customer{…} argument is in run-time).
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









