1

I am an absolute beginner in Elixir and I tried toying around with recursion by making a function like this:

  def player_choice() do
    choice = IO.gets("Choose rock, paper or scissors: ") |> String.trim()

    unless String.downcase(choice) in ["rock", "paper", "scissors"] do
      IO.puts("\nPlease insert a valid move")
      choice = player_choice()
    end

    choice
  end

So if someone inputs a value thats not expected the function should continue asking for an input. But if the first input is something unexpected like "no", and the next input is "rock" the function will return "no". Why does this happen, shouldn't "choice" be the reassigned value?

2 Answers 2

2

The problem is that you redefine a new variable choice in your internal unless, masking the outer one (in Elixir, you don't "reassign"). The compiler warns you:

variable "choice" is unused (there is a variable with the same name in the context

A better solution would be something like:

def player_choice() do
  choice = IO.gets("Choose rock, paper or scissors: ") |> String.trim() |> String.downcase
  if choice in ["rock", "paper", "scissors"] do
     choice
  else
     IO.puts("\nPlease insert a valid move")
     player_choice()
  end
end
Sign up to request clarification or add additional context in comments.

1 Comment

Small precision: you can reassign in elixir, but it only affects the scope of the current block. It has no effect outside of an if / for block if declared inside.
2

Pattern matching seems an idiomatic way to approach this

defmodule Playground do
  def player_choice(choice) when choice in ["rock", "paper", "scissors"], do: choice
  def player_choice(_) do
    IO.puts("\nPlease insert a valid move")
    prompt()
  end
  
  def prompt() do
    IO.gets("Choose rock, paper or scissors: ") 
    |> String.trim
    |> String.downcase 
    |> Playground.player_choice
  end
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.