I'm in the process of breaking our larger/monolithic app into separate
repos so we can bring the pieces in as dependencies on other apps.
However, a key problem we are running into is ultimately around the
database models.
We're working on a separate thing around most of that, but at the heart
the problem comes in that we are one level too far removed, so a LOT of
warnings appear during compile, even though they aren't relevant at
runtime — notably stuff like below on the dependency compile.
warning: Core.Repo.transaction/2 is undefined (module Core.Repo is not
available or is yet to be defined)
lib/rivet/ecto/collection/general.ex:21: Rivet.Ident.Action.full_table_scan/2
I've looked at how oban handles it, and they setup an inefficient layer
of indirection (obfuscation) to hide the warning.
The problem I have is this is what I'd call a developer vanity change.
It serves NO purpose other than to hide a compiler warning, but the
side-effect is less efficient code during runtime.
The resulting code with a warning includes the atom for the repo module,
and everything works fine. The warnings are legitimate in the myopic
context of compiling ONLY the dependency, but are not correct when
considering the complete application.
I could perhaps add something like `[xref: [exclude: [Core.Repo]]]` to
the dependent library's project data/mix.exs, and that might be fine for
a closed-world where we don't share the library. But we are considering
opening the library to the public, so this isn't a valid solution.
I feel like this same problem is resolved with umbrella applications.
Which makes me wonder, perhaps there could be a way to treat an external
dependency like a member of the umbrella, and inject stuff like the xref
in at the deps() array level, rather than from within that project?
While I'm not a fan of premature optimization, but I do care about
keeping in mind the things that will have a potential of high-frequency
calls, and avoiding doing anything obviously dangerous with those,
especially over just a vanity thing.
In this case the warning isn't a real problem, it's just something the
compiler thinks could be a problem.
Is there some other way to do this short of putting in a less efficient
abstraction layer just to make it so the compiler can't detect what's
really happening?
I'm just throwing mud on the wall now but something like:
{:included_thing, "~> 1.2.3", xref: [exclude: [Core.Repo]]},
Ultimately, the problem I have with all of the hereto offered solutions
is that they effectively boil down to "obfuscate your code enough that
the compiler won't throw a warning."
But that's seriously misaligned in my opinion.
The goal of coding should be (a) creating simple but efficient code to
execute in production that is (b) readable and maintainable. These
obfuscation/vanity recommendations violate both of these points.
I don't know what the right solution is. I just feel like there should
be something better than what's there now.
-Brandon
--
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/4b127f8b-ddcb-b25e-0e7c-12af3af68252%40cold.org.