CLI worm animation

Hello fellow alchemists,

I’m relatively new to Elixir and have been trying to use OTP concepts with Processes to make a worm animation type thing in the command line. Here’s my code:

defmodule TitleGraphics do
  def start do
    loop_pid = spawn(Loop, :start, [])
    Process.link(loop_pid)
    send(loop_pid, {:send_pid, self()})
  end
end

defmodule Loop do
  def display_worm_wiggle do
    frames = ["_","-","_","-","_","-","_","-"]
    Enum.each(frames, fn frame -> IO.write("\r#{frame}")
    Process.sleep(200) end)
  end

  def start do
    receive do
      {:send_pid, :sender_pid} ->
        display_worm_wiggle()
    end
  end
end

→ I’ve made two modules: 1 to start the loop and create a link between this process and the other which does the actual printing of the worm. I don’t know why, but the process just returns its pid, and doesn’t start printing. Help would be much appreciated >.<

Hello and welcome,

please remember to wrap your code with ``` (3 backticks) for formatting.

I did the modifications this time…

1 Like

This pattern is looking for a tuple of two atoms, :send_pid and :sender_pid. This does not match what you send it, which is a tuple of an atom and a pid.

I think you meant to make the second thing a variable:

      {:send_pid, sender_pid} ->
3 Likes

I like your creative idea for learning the language.

2 Likes

Will do, thanks.

Thanks XD

Much appreciated :pray:

abshdjsb

I’ve done it!
Here’s the finished code for whomever it may concern (Elixir noobies):

defmodule TitleGraphics do
  def start do
    loop_pid = spawn(Loop, :loop, [])
    #Process.link(loop_pid)
    send(loop_pid, {:start_pid, self()}) # self is the pid of the current process
    loop_pid
  end

  def stop(pid) do
    Process.exit(pid, :ok)
  end
end

defmodule Loop do
  def loop do
    frames = ["_.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._",
    ".-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.",
    "-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-"]
    receive do
      {:start_pid, sender_pid} -> loop(frames)
    end
  end

  defp loop(frames) do
    Enum.each(frames, fn frame -> IO.write("\r#{frame}")
    Process.sleep(200)
      end)
      loop(frames)
  end
end 
3 Likes

Hi @theneroc I’m glad it worked for you! As a small forum etiquette note, please don’t create multiple individual replies, just use one reply and @ people if you want to mention them specifically.

Congrats on your first project!

1 Like