Open nietaki opened 1 week ago
iex
calls inspect/2
on the result of any function and that's what is displays in the terminal. As of a ex_cldr
2.38.0 on April 21st, the Inspect
protocol implementation for Cldr.LanguageTag.t
changed to output executable code when the locale has been resolved to a known/configured locale. So while you see MyApp.Cldr.Locale.new!("en-US")
in the terminal, the result is actually a struct.
I made this change to be consistent with how Inspect
implementations are evolving in the Elixir code base - more towards inspect producing executable code in more situations.
Does that clear up what you're seeing?
It seems like an astounding anti-pattern for a number of reasons:
Repro.Cldr.Locale.new!("en-US") |> Map.from_struct()
? Knowing the stuct by heart and just fetching its fields blindly?Cldr.LanguageTag.t
was to keep just the data, it wouldn't be able to return the function description, because it wouldn't have a reference to the backend used to create it.inspect()
itself not serve its purpose - I'm not inspecting the terms contents, just a random way to create it.Cldr.Locale.new("en-ES", TestBackend.Cldr)
{:ok, %Cldr.LanguageTag{
backend: TestBackend.Cldr,
canonical_locale_name: "en-ES",
# (lines cut)
script: :Latn,
territory: :ES,
transform: %{},
language_variants: []
}}
I hoped that worst case scenario this was a ham-handed way of ex_cldr
to let me know I should be using the Myapp.Cldr
module instead of the Cldr
module, so kept on re-checking my config. I'd check the source of Myapp.Cldr
to see what's going on, but I skipped that, because it's macro-generated.
I made this change to be consistent with how Inspect implementations are evolving in the Elixir code base - more towards inspect producing executable code in more situations.
Do they really? All of the examples I can find right now have the Inspect
protocol implementation return all the relevant/usable information about the underlying term:
iex(7)> ~r/(foo|bar)/u
~r/(foo|bar)/u
iex(8)> spawn fn -> 1 end
#PID<0.110.0>
iex(9)> pid(0, 110, 0)
#PID<0.110.0>
iex(10)> MapSet.new([:foo, :bar, :bar])
MapSet.new([:foo, :bar])
iex(11)> MapSet.new([:foo, :bar])
MapSet.new([:foo, :bar])
iex(12)> URI.new!("https://example.com/en/?foo=bar#header")
%URI{
scheme: "https",
userinfo: nil,
host: "example.com",
port: 443,
path: "/en/",
query: "foo=bar",
fragment: "header"
}
iex(13)> Repo.get!(PersonGroup, "b9a57dde-52b9-4e71-b300-98d6433b9a79")
%Foo.Models.PersonGroup{
__meta__: #Ecto.Schema.Metadata<:loaded, "persons_groups">,
id: "b9a57dde-52b9-4e71-b300-98d6433b9a79",
person_id: "85d52529-49af-4662-b432-9eec82254adf",
person: #Ecto.Association.NotLoaded<association :person is not loaded>,
group_id: "9092bad9-f64a-4bd7-951d-6e38fbdbcbea",
group: #Ecto.Association.NotLoaded<association :group is not loaded>,
inserted_at: ~U[2024-03-14 16:57:47.121775Z]
}
Yes, I don't see the whole structure of MapSet
or Ecto.Association.NotLoaded
, but that's because it's very difficult for me to come up with a reson why I would care about them.
What you did, however, is the equivalent of this:
iex(12)> URI.new!("https://example.com/en/?foo=bar#header")
URI.new!("https://example.com/en/?foo=bar#header")
iex(13)> Repo.get!(PersonGroup, "b9a57dde-52b9-4e71-b300-98d6433b9a79")
Repo.get!(PersonGroup, "b9a57dde-52b9-4e71-b300-98d6433b9a79")
Which in my opinion is incredibly pointless and unhelpful.
Also, please don't get me wrong, it's not like I wasn't aware of the Inspect
protocol - it's just that in my decade of working with Elixir I wouldn't come up with someone using it this way. It might sound like I'm annoyed by this situation, and that's only because it's true - this "feature" cost me over an hour of my life, debugging an issue that's not there.
So the answer does clear up what I'm seeing, but makes the intentions before the decision to make it this way even more bizarre.
I have posted in Elixir Forum on this topic to see what community and Elixir core team views are on this.
I used
ex_cldr
before, which is why I wanted to use it to fetch some information for a number of locales.When I add it to a project (a real one or a repro one), most of the functions I run return
MyApp.Cldr.Locale.new!("en-US")
for whatever reason.I created a repo with the repro. I tried to keep the configuration minimal:
I re-read the installation/configuration docs a couple of times and fiddled with the config and I'm still getting the same results.
Any advice? I assume (hope) this isn't the expected behaviour.
Edit: I updated the issue title to be actionable.