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.

Reply via email to