There's also an option of pattern matching any struct, not exactly a guard, but changing your code a bit shouldn't be a problem
``` def foo(%_{} = _struct), do... def foo(map) when is_map(map), do... ``` Sent from Proton Mail mobile -------- Original Message -------- On 4 Jan 2023, 04:03, Jay Rogov wrote: > Also note that there's is_map_key/2 guard that serves the same purpose when > used as `is_map_key(arg, :__struct__)`, allowing only maps but not structures: > https://hexdocs.pm/elixir/1.14.2/Kernel.html#is_map_key/2 > > On Thursday, 22 December 2022 at 4:22:30 pm UTC+1 halos...@gmail.com wrote: > >> I think that this is an interesting idea, but as Enumerable is a protocol, >> it is possible to implement enumerability for any given struct, as `MapSet` >> is enumerable. >> >> This [SO >> answer](https://stackoverflow.com/questions/39609255/how-can-i-check-whether-the-protocol-is-implemented#39609295) >> suggests using the Protocol.impl_for/1 callback instead. It can’t be used >> as a guard, but it gives a more accurate answer. >> >> Whether `is_real_map/1` (or a different name) is more readable than `when >> is_map(term) and not is_struct(term)`, I can’t say because if I need to >> handle structs differently, I would generally use two different function >> heads (`def foo(term) when is_struct(term) do term |> Map.from_struct() |> >> foo() end` and `def foo(term) when is_map(term) do … end`). >> >> -a >> >> On Thu, Dec 22, 2022 at 1:25 AM vtm <vtmil...@gmail.com> wrote: >> >>> hey all, thanks for you work on such a beautiful lang. >>> >>> Small proposal. People sometimes get confused about data structures which >>> based on maps. >>> for instance: >>> ``` >>> iex(3)> {:ok, datetime} = DateTime.now("Etc/UTC") >>> {:ok, ~U[2022-12-22 05:53:36.228720Z]} >>> iex(5)> is_struct(datetime) >>> true >>> iex(6)> is_map(datetime) >>> true >>> ``` >>> but here i got an error >>> ```elixir >>> iex(11)> Enum.each(datetime, &Function.identity/1) >>> ** (Protocol.UndefinedError) protocol Enumerable not implemented for >>> ~U[2022-12-22 05:53:36.228720Z] of type DateTime (a struct) >>> ``` >>> >>> i have in a codebase in function definition something like >>> `where is_map(map_name) and not is_struct(map_name)` >>> what i suggest to do is to create a macro `is_real_map` to check only real >>> maps as a key-value storage with Enumerable impl >>> ```elixir >>> @doc """ >>> Returns true if `term` is a map and not is struct; otherwise returns >>> `false`. >>> >>> Allowed in guard tests. >>> >>> ## Examples >>> >>> iex> is_real_map(%{oi: :blz}) >>> true >>> >>> iex> is_real_map(URI.parse("/")) >>> false >>> >>> """ >>> @doc since: "1.16.0", guard: true >>> defmacro is_real_map(term) do >>> case __CALLER__.context do >>> nil -> >>> quote do >>> case unquote(term) do >>> %_{} -> false >>> %{} -> true >>> _ -> false >>> end >>> end >>> >>> :match -> >>> invalid_match!(:is_real_map) >>> >>> :guard -> >>> quote do >>> is_map(unquote(term)) and not :erlang.is_map_key(:__struct__, unquote(term)) >>> end >>> end >>> end >>> ``` >> >>> -- >>> You received this message because you are subscribed to the Google Groups >>> "elixir-lang-core" group. >>> To unsubscribe from this group and stop receiving emails from it, send an >>> email to elixir-lang-co...@googlegroups.com. >>> To view this discussion on the web visit >>> [https://groups.google.com/d/msgid/elixir-lang-core/1f26dae3-9c67-446b-91d0-51bf1c5f3666n%40googlegroups.com](https://groups.google.com/d/msgid/elixir-lang-core/1f26dae3-9c67-446b-91d0-51bf1c5f3666n%40googlegroups.com?utm_medium=email&utm_source=footer). >> >> -- >> >> Austin Ziegler • halos...@gmail.com • aus...@halostatue.ca >> http://www.halostatue.ca/ • http://twitter.com/halostatue > > -- > You received this message because you are subscribed to the Google Groups > "elixir-lang-core" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to elixir-lang-core+unsubscr...@googlegroups.com. > To view this discussion on the web visit > [https://groups.google.com/d/msgid/elixir-lang-core/90368793-c5b7-47d2-9dfd-f0ee6221f387n%40googlegroups.com](https://groups.google.com/d/msgid/elixir-lang-core/90368793-c5b7-47d2-9dfd-f0ee6221f387n%40googlegroups.com?utm_medium=email&utm_source=footer). -- You received this message because you are subscribed to the Google Groups "elixir-lang-core" group. To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/gCO3cNmTH8s-grC61yt_KsSqoJ5CCZzYiPqA5X0S3Q1ZgoZ8j7usrix2xMFr-iGAdSl5X_N1NM-mvniP4KoOnkD1bRsrmtMoln_80Jk4v4A%3D%40pm.me.