eksperimental
Conditional import and lexical scope
Is there a way to conditionally import a function, but make the import available outside the if or case?
this obviously works:
def foo() do
import Enum, only: [map: 2]
map(1..5, &IO.inspect(&1))
end
this works as well:
if is_integer(term) do
import Enum, only: [map: 2]
map(1..term, &IO.inspect(&1))
end
this does not work due to lexical scope.
if true do
import Enum, only: [map: 2]
end
map(1..integer, &IO.inspect(&1))
So far so good.
My question is, how can we import conditionally at runtime, and make the import available outside the condition clause.
The only solution that I thought it could make it work was this, it does not and it baffles me.:
true && (import Enum, only: [map: 2])
map(1..integer, &IO.inspect(&1))
Note: for my use case I can solve this by running the condition at compile time, but I am just trying to understand how to do it at runtime.
Thank you
Marked As Solved
al2o3cr
The behavior makes sense if you look at the implementation:
https://github.com/elixir-lang/elixir/blob/74bfab8ee271e53d24cb0012b5db1e2a931e0470/lib/elixir/lib/kernel.ex#L3791-L3803
The right-hand expression in && winds up inside a case statement, so the import does not leak out.
Also Liked
LostKobrakai
That’s what I’d do, which seems a lot cleaner than conditionally importing things.
mod = if condition, do: Stream, else: Enum
mod.map(1..integer, &IO.inspect(&1))
ityonemo
Imports are compile-time.
dimitarvp
Elixir being FP I don’t see any other way except closures or just passing a function like so
defmodule Helper
if compile_time_condition do
def with_scope(fun) do
import Enum
fun.()
end
else
def with_scope(fun) do
import Stream
fun.()
end
end
end
Or you can do it with a keyword list parameter with :do and :else like the if macro does.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance










