This is not generally true in Elixir - all of the references in this example compile to a single entry in the LitT
literal chunk:
defmodule Foo do
@attr_version %{
a: 1,
b: 2,
c: 3
}
def attr_lookup(x), do: Map.get(@attr_version, x)
def inline_lookup(x), do: Map.get(%{a: 1, b: 2, c: 3}, x)
def variable_lookup(x) do
map = %{
a: 1,
b: 2,
c: 3
}
Map.get(map, x)
end
end
The Elixir compiler can safely make this optimization since values can’t ever be mutated - this is different from languages like Ruby where a literal constructed inside a method has to be distinct since it could be subsequently changed. For instance:
class Foo
ALWAYS_THE_SAME = {a: 1, b: 2, c: 3}
def self.as_constant
ALWAYS_THE_SAME
end
def self.as_local
{a: 1, b: 2, c: 3}
end
end
puts Foo.as_constant.object_id == Foo.as_constant.object_id
puts Foo.as_local.object_id == Foo.as_local.object_id
prints true
followed by false
, because the result from as_local
is a different object every time.