MickeyOoh
"defstruct" diffrenet behaviors in iex and elixir
Programming Elixir page 80 about “defstruct”
I first ask question and I am a quite beginner. I followed this book again to confirm each steps’ process.
Following book by using iex, it works. But implemented IO.puts into code and did “Elixir defstruct.exs” so that it didn’t work with Error.
please help me why the error occur and how to solve this.
code:
defmodule Subscriber do
defstruct name: "", paid: false, over_18: true
end
s1 = %Subscriber{}
IO.puts inspect(s1)
Error:
** (CompileError) defstruct.exs:5: cannot access struct Subscriber, the struct was not yet defined or the struct is being accessed in the same context that defines it
Marked As Solved
peerreynders
The issue is with the phases that the Elixir compiler goes through.
While this
defmodule Subscriber do
defstruct name: "", paid: false, over_18: true
end
s1 = %Subscriber{}
IO.puts inspect(s1)
results in an error, the following does not
defmodule Subscriber do
defstruct name: "", paid: false, over_18: true
def new,
do: %Subscriber{}
end
s1 = Subscriber.new()
IO.puts inspect(s1)
During compilation the expansion phase happens before the evaluation phase. However the functionality of a module isn’t “defined” and available until it has been evaluated during the evaluation phase. So when the compiler comes across
s1 = %Subscriber{}
during the expansion phase it tries to expand %Subscriber{} - the problem is that %Subscriber{} is part of the Subscriber module which won’t be defined until later in the evaluation phase - so during the expansion phase there is no definition for %Subscriber{} (yet).
s1 = Subscriber.new()
doesn’t have anything to expand - it is simply a function call that is evaluated during the evaluation phase - by that point in time the Subscriber module has been fully evaluated and both %Subscriber{} and Subscriber.new() are defined and available.
See also
Also Liked
NobbZ
I do not think so!
Defining a struct and using it in the following script is essential in scripting with elixir.
MickeyOoh
peerreynders, Thank you so much.
I corrected my codes as what you said and it works. And I learned a lot from you.
modified code:
defmodule Subscriber do
defstruct name: "", paid: false, over_18: true
def run do
s1 = %Subscriber{}
IO.puts inspect(s1)
s2 = %Subscriber{name: "Dave"}
IO.puts inspect(s2)
s3 = %Subscriber{ name: "Mary", paid: true}
IO.puts inspect(s3)
IO.puts "#{s3.name}"
%Subscriber{name: a_name} = s3
IO.puts a_name
s4 = %Subscriber{ s3 | name: "Marie"}
IO.puts inspect(s4)
end
end
Subscriber.run()
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








