MickeyOoh

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

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

https://groups.google.com/d/msg/elixir-lang-talk/5Zj32zJssl8/wPJZioP9lUEJ

Main phases of Elixir compilation

Also Liked

NobbZ

NobbZ

I do not think so!

Defining a struct and using it in the following script is essential in scripting with elixir.

MickeyOoh

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()

Where Next?

Popular in Questions Top

pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
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
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
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
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
kostonstyle
Hi all I want to have a unix time, from the current time plus 1 hour. DateTime.now + 1 hour How to get it in elixir? Thanks
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
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
Mooodi
Given a string, how can I get access to its character by index? Enum.at("my_string", 2) doesn't work. Or rather, not char, but a substr...
New

Other popular topics Top

JDanielMartinez
Hi! May someone helps me, please! I have two apps into an umbrella project: the first one is Database, which manages queries, and the se...
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
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
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
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
chensan
I have a User schema with a :from_id field set to type :string: defmodule TweetBot.Repo.Migrations.CreateUsers do use Ecto.Migration ...
New
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
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New

We're in Beta

About us Mission Statement