Packages

Scope is a small module that provides two macros to facilitate function overload and local import/aliases execution.

Current section

Files

Jump to
scope lib scope.ex
Raw

lib/scope.ex

defmodule Scope do
@moduledoc """
Scope is a small module that provides two macros to facilitate
function overload and local import/aliases execution.
## Overload functions
```
import Scope
overload [+: 2, -: 2], from: Kernel, with: Test
1 + 3 - 2 # gives [2, [1, 3]]
```
## Local importation
You can just import one or more module :
```
import Scope
x = local System do
user_home <> " !"
end
# Or multiple module
y = local Elixir.{System, Path} do
absname(user_home())
end
# Or specifics function from a module
z = local [user_home: 0, user_home!: 0] in System do
user_home <> " !"
end
```
You can also directly use an expression:
```
import Scope
a = local (overload [+: 2, -: 2], from: Kernel, with: Test) do
1 + 2 - 3
end
b = 1 + 2 - 3
# a == [3, [1, 2]]
# b == 0
c = local (import Test) do
a = 1 + 2
b = 1 - 2
a - b
end
```
"""
@doc false
def __using__(_opts) do
quote do: (import Scope)
end
@doc """
Import module `from` except the gived functions and
import module `with` with only the gived functions.
This is mainly useful for overloading operators used in `Kernel`.
(Arithmetics operators for example)
"""
defmacro overload(methods, from: a, with: b) do
quote do
import unquote(a), except: unquote(methods)
import unquote(b), only: unquote(methods)
end
end
@doc """
Generate the execution of a lambda, with the importation
of the gived module expression.
"""
defmacro local(module_expr, body)
defmacro local({:in, _, [kw, module]}, do: expr) do
quote do
local(
(import unquote(module), only: unquote(kw)),
do: unquote(expr)
)
end
end
defmacro local({:__aliases__, _, [_]} = module, do: expr) do
quote do
local(
(import unquote(module)),
do: unquote(expr))
end
end
defmacro local(module_expr, do: expr) do
quote do
fn() ->
unquote(module_expr)
unquote(expr)
end.()
end
end
end