a-maze-d

a-maze-d

Defguard with conflicting imports

Hello all,

I got an issue in defining a defguard which is a combination of already existing defguards. Example:

defmodule Combined do
  import A
  import B

  defguard is_color_name(atom) when 
    is_color_name_from_A(atom) or
    is_color_name_from_B(atom)
end

defmodule A do
  defguard is_color_name_from_A when ...
end

defmodule B do
  defguard is_color_name_from_B when ...
end

The above should (I haven’t tried it) work, but in my case the guard names in the modules A and B are the same (is_color_name coming from different sources)

It seems that the guards NEED to be imported otherwise I get a cannot call remote function inside guard when trying to alias them. I also can’t use the lexical scope trick mentioned in the documentation by wrapping it in a function (because I would still need to import A and B) and I also can’t rename the functions/guards during import (like renaming aliases

I can solve my problem in a not so elegant way (because I have control over A and B), but I would prefer to learn about some trick that could help to solve this problem (and if there is none, then maybe the question whether something is missing in the language)

Happy to hear your (expert) ideas :slight_smile:

Marked As Solved

sodapopcan

sodapopcan

In short, no there is no way around this (AFAIK, at least).

Guards are macros that are run at compile time, this is why you need to import them (you could also require them if you wanted). Compile-time pretty much boils down to “inside the module’s body” though also applies to guards: the block given to when is evaluated at compile time only, as opposed to the block given to do which is evaluated at runtime. This is why the scoping trick won’t work as the import inside the function’s body is checked at runtime.

Finally, the reason you can’t rename functions on import is because import doesn’t work like I’m assuming you think it does. It doesn’t “bring functions into a module” it really just “opens up its scope for function resolution,” hence the name “remote” function. When you do import Foo, only: [bar: 1] then call bar(), the compiler essentially rewrites it to Foo.bar(). I suppose function aliases could be a thing, though I never really thought of it :thinking:

In any event, all that to say, an option would be to just require instead of import, then you can do:

defmodule Combined do
  require A
  require B

  defguard is_color_name(atom) when 
    A.is_color_name_from_A(atom) or
    B.is_color_name_from_B(atom)
end

EDIT: Oh, @hauleth beat me to the same advice :upside_down_face: I just shouldn’t have been so wordy :sweat_smile:

Also Liked

hauleth

hauleth

Require modules and do qualified calls, it should still work

a-maze-d

a-maze-d

This works. Thanks for your help

Where Next?

Popular in Questions Top

Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
Tee
can someone please explain to me how Enum.reduce works with maps
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
itssasanka
Hi all, Trying to get some more clarity over utc_datetime and naive_datetime for Ecto: https://hexdocs.pm/ecto/Ecto.Schema.html#module-...
New
logicmason
Hi there, I'm working through my first release with elixir/phoenix. I've built a release with distillery and found that it crashes when I...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? https://hexdocs.pm/ecto/Ecto.Repo.h...
New
Exadra37
Sometimes I want to check if the input into a function is not a blank string. My first approach: defmodule Example do def do_stuff(s...
New
jc00ke
Expanding on this topic: https://forum.elixirforum.net/t/map-typespec-question/19217 Let’s say I have a map with required and optional k...
New

Other popular topics Top

shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1140 51847 244
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
977 41022 311
New
sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 49522 488
New
polypush135
As many of you may have realized by now (sorry for all the posts here) I’ve been working on a db problem where I’m trying to aggregate a ...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
New

We're in Beta

About us Mission Statement