Hi guys!
I’m a beginner user in Elixir. I wrote a small program using Mix project. It’s work fine when I run my app with “mix run”, but when I use “iex -S mix” (for debug) I can’t type anything in terminal and I need to use ctrl+C for exit.
Hi guys!
I’m a beginner user in Elixir. I wrote a small program using Mix project. It’s work fine when I run my app with “mix run”, but when I use “iex -S mix” (for debug) I can’t type anything in terminal and I need to use ctrl+C for exit.
No idea what is going on there. Are you calling iex -S mix
from within the root directory of your project? Are you able to just run iex normally?
Yes, iex
console it’s working.
I run in terminal inside vscode, mix run
works fine, but iex -S mix
not. I tested in terminal outside vscode and the same error happens too.
Hey @alrigotto welcome! This usually means that one of your supervisor’s children has hung and so the app is unable to boot. If you do iex -S mix run --no-start
do you get a REPL? Can you show your application.ex file?
Hi benwilson!
I did iex -S mix run --no-start
and get normaly REPL.
I guess this problem started when I was made several debug testing for learning.
I wonder if this changed some file inside mix folder project, because new projects are working fine.
My app.ex:
It’s a simple guess number game tutorial.
defmodule GuessGame do
use Application
def start(_,_) do
run()
{:ok, self()}
|> IO.inspect(label: "run after2")
end
def run() do
IO.puts("Let's pĺay Guess the Number")
IO.gets("Choose a dificult level (1, 2 or 3):")
# the "|>" (pipe) operator in Elixir put the output from the previous line to the first function's argument in the next line
|> parse_input()
|> pickup_number()
|> IO.inspect(label: "Before play()")
|> play()
|> IO.inspect(label: "After play()")
# require IEx; IEx.pry
end
def pickup_number(level) do
level
|> IO.inspect()
|> get_range()
|> IO.inspect()
|> Enum.random()
end
def play(picked_num) do
IO.gets("I have my number. What is your guess?")
|> parse_input()
|> guess(picked_num, 1)
end
# In the function 'guess()' is being used 'Guards' technique in Elixir
def guess(usr_guess, picked_num, count) when usr_guess > picked_num do
IO.gets("Your number is too high. Guess again: ")
|> parse_input()
|> guess(picked_num, count + 1)
end
def guess(usr_guess, picked_num, count) when usr_guess < picked_num do
IO.gets("Your number is too low. Guess again: ")
|> parse_input()
|> guess(picked_num, count + 1)
end
# the last option for 'guess()' (guards)
def guess(_usr_guess, _picked_num, count) do # '_' underscore makes the arguments to be ignored
IO.puts("You got it #{count} guess. ")
show_score(count)
end
def show_score(guesses) when guesses > 6 do
IO.puts("Better luck next time!")
end
def show_score(guesses) do
{_, msg} = %{1..1 => "You're a mind rider!",
2..4 => "Most impressive!",
3..6 => "You can do better than that!"}
|> Enum.find(fn {range, _} -> Enum.member?(range, guesses) end)
IO.puts(msg)
end
# The function "parse-input" is defined twice (it could be more) because Elixir has this feature where is possible...
#...to choose what the functions will be used based on its argument.
# if the player set a non number a ":error" will come up, so the game will ru again after a message error.
def parse_input(:error) do
IO.inspect(label: ":erro")
IO.puts("Invalid level!!!")
run()
end
# if the player set a number, this number will be returned.
def parse_input({num, _}), do: num #one line def function
def parse_input(data) do
data
|> Integer.parse()
|> IO.inspect()
|> parse_input()
|> IO.inspect()
end
def get_range(level) do
case level do
1 -> 1..10 # define a range in Elixir
2 -> 1..100
3 -> 1..1000
# in case the player set a number higher than 3 (max level)
_ -> IO.puts("Invalid level--------!!!")
run()
end
end
def teste() do
IO.getn("dsdsd: ")
|> IO.puts()
end
end
Thank you for your support!
Looks like you use this code at application start.
That’s good for normal app start or script, but when your are using iex
then IO.gets/1
is blocking shell. Running the game in supervised task also does not solves the problem.
The only way to “play” a game in iex
(using IO.gets/1
) is to call the code directly from shell instead of adding it to application supervisor tree. However in that case when starting app normally the game would not run.
Therefore I would suggest to check some args/environment variables, so for some runs simply start the game automatically and when using iex
shell start the game manually, for example:
defmodule GuessGame do
use Application
def start(_,_) do
if some_check_here do
run()
end
{:ok, self()}
end
# …
end
iex> GuessGame.run()
I could be wrong but I’m pretty sure that returning {:ok, self()}
from start is also a problem. The application root needs to be an actual supervisor, not whatever pid is booting the app.
Thank you guys for your helps.
I’ll try to use your tips.
As a beginner this problem is a bit complex than I expected, I thought that was only a beginner’s mistake.
I have a lot of basic things to learn in Elixir, mainly in Mix projects.
Thank you again!!
Also, might I suggest using the 1.14 version of elixir and the new dbg features?
The IEX+dbg and pipeline debugging will make your live much better, and remove the need for the many inspects.
The videos on that link give a view of how it can help you.