Cannot create constants in Elixir module

Code

I am still going though the feedback of some of my posts. One of the them is the rotational cypher, which I have upgraded to the follow more readable format:

defmodule RotationalCipher do
  @alphabet_size 26

  defguard is_lower?( char) when char in ?a..?z
  defguard is_upper?( char) when char in ?A..?Z

  @doc """
  Given a plaintext and amount to shift by, return a rotated string.

  Example:
  iex> RotationalCipher.rotate("Attack at dawn", 13)
  "Nggnpx ng qnja"
  """
  @spec rotate(text :: String.t(), shift :: integer) :: String.t()
  def rotate(text, shift) do
    text
    |> String.to_charlist()
    |> Enum.map( &spin(&1, shift) )
    |> to_string()
  end

  defp spin( char, shift ) when is_lower?( char ), do: ?a + rem( char - 71 + shift, alphabet_size )
  defp spin( char, shift ) when is_upper?( char ), do: ?A + rem( char - 39 + shift, alphabet_size )
  defp spin( char, _ ), do: char
end

Problem

However, when trying to run it, I get the following error:

warning: variable “alphabet_size” does not exist and is being expanded to “alphabet_size()”, please use parentheses to remove the ambiguity or change the variable name
rotational_cipher.exs:22

warning: variable “alphabet_size” does not exist and is being expanded to “alphabet_size()”, please use parentheses to remove the ambiguity or change the variable name
rotational_cipher.exs:23

** (CompileError) rotational_cipher.exs:22: undefined function alphabet_size/0
(stdlib) lists.erl:1338: :lists.foreach/2
(stdlib) erl_eval.erl:680: :erl_eval.do_apply/6

Question

For some reason, my constant alphabet_size is not being recognized as such and thus everything breaks. I am following to docs, so I don’t get why this isn’t working:

https://elixir-lang.org/getting-started/module-attributes.html#as-constants

What am I doing wrong?

Shouldn’t you use @alphabet_size instead of alphabet_size?

7 Likes