I can create a keyword list only with an atom of type :atom
, but not Foo
. Why is that?
iex(1)> [foo: "bar"]
[foo: "bar"]
iex(2)> is_atom(Foo)
true
iex(3)> [Foo "bar"]
** (SyntaxError) iex:3: syntax error before: "bar"
iex(3)>
I can create a keyword list only with an atom of type :atom
, but not Foo
. Why is that?
iex(1)> [foo: "bar"]
[foo: "bar"]
iex(2)> is_atom(Foo)
true
iex(3)> [Foo "bar"]
** (SyntaxError) iex:3: syntax error before: "bar"
iex(3)>
yes, keyword is internally alist of tuples where first element is atom, second value. If you want different type as keys, you need to use something lime Map.
To rephrase slightly, if :foo
and Foo
are both atom, why doesn’t the latter work in a Keyword list?
Of course you can use Foo
as keyword in a Keywordlist, but you do not have syntactic sugar then (or you have to spell it out)
iex(1)> [{Foo, "bar"}]
[{Foo, "bar"}]
iex(2)> ["Elixir.Foo": "bar"]
[{Foo, "bar"}]
iex(3)> Keyword.fetch(v(2), Foo)
{:ok, "bar"}
you can,
you need to use the semi-colon
iex> [Foo: “bar”]
[Foo: “bar”]
This one renders the first term as :Foo
however.
iex(1)> kw = [Foo: "bar"]
[Foo: "bar"]
iex(2)> Keyword.get(kw, :Foo)
"bar"
iex(3)> Keyword.get(kw, Foo)
nil
I got @NobbZ 's approach I got to work.
iex(6)> kw = [{Foo, "bar"}]
[{Foo, "bar"}]
iex(7)> Keyword.get(kw, Foo)
"bar"
iex(8)> is_atom(Foo)
true
Thanks everyone!
Foo is a shorthand for Elixir.Foo
that is why it doesn’t work
There is a slight difference between Foo
and :Foo
! The first is an alias which expands to an atom prefixed by :Elixir.
but the exact name depends on the context. :Foo
on the other hand will not be expanded to anything but is always the same value regardless of context.
defmodule A do
alias Foo, as: Bar
def check(Bar), do: true
def check(_), do: false
end
IO.puts A.check(Foo) #=> true
IO.puts A.check(Bar) #=> false
That code looks a bit clunky though and is untreated since I’m on my mobile right now.
edit: Tested and repaired the example.
No, for :"Elixir.Foo"
or whatever else you alias it to…
ah yes, sure. As others suggested you can do that but it sort of looses the appeal if you do that without syntactic sugar this way.