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

Last Post!

a-maze-d

a-maze-d

This works. Thanks for your help

Where Next?

Popular in Questions Top

JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New

Other popular topics Top

lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
AstonJ
Seen any cool LiveView demos, sample apps or examples? Please post them here! :003:
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New

We're in Beta

About us Mission Statement