2

In hexpm project, The line cast(%User{}, params, ~w(username full_name password)a). I know it may be equal to [:username, :full_name,:password], but why? What's the meaning of ~w and a?

  def build(params, confirmed? \\ not Application.get_env(:hexpm, :user_confirm)) do
    cast(%User{}, params, ~w(username full_name password)a)
    |> validate_required(~w(username password)a)
    |> cast_assoc(:emails, required: true, with: &Email.changeset(&1, :first, &2, confirmed?))
    |> cast_embed(:tfa)
    |> update_change(:username, &String.downcase/1)
    |> validate_length(:username, min: 3)
    |> validate_format(:username, @username_regex)
    |> validate_format(:username, @username_reject_regex)
    |> validate_exclusion(:username, @reserved_names)
    |> unique_constraint(:username, name: "users_username_idx")
    |> validate_length(:password, min: 7)
    |> validate_confirmation(:password, message: "does not match password")
    |> update_change(:password, &Auth.gen_password/1)
  end
Adam Millerchip
  • 20,844
  • 5
  • 51
  • 74
Chen Yu
  • 3,955
  • 1
  • 24
  • 51

1 Answers1

3

See the docs for ~w.

~w(username full_name password)a is just a shorthand for writing [:username, :full_name, :password]. It may have been inspired by Perl's Quote-Like Operators.

  • The ~w sigil tells elixir that the space-separated items should be a list.
  • the a modifier tells it that the items are atoms.

Considering code is read much more often than written, I personally do not use this sigil. Writing [:username, :full_name, :password] directly does not take much effort and avoids questions like this from both newbies that have never seen the sigil, and for old hands that don't remember the modifiers.

Adam Millerchip
  • 20,844
  • 5
  • 51
  • 74
  • 1
    sigils are more useful for complicated data like dates. Just for fun, here is my implementation of sigils for the bioctal format of RFC 9226 (yes, a 1st April RFC). https://www.bortzmeyer.org/bioctal.html – bortzmeyer Sep 04 '22 at 14:53