# Atadura
[![Build Status](https://travis-ci.org/am-kantox/atadura.svg?branch=master)](https://travis-ci.org/am-kantox/atadura)
**Helper tiny module to provide easy binding support as `bind_quoted` does for `quote do`.**
## Installation
```elixir
def deps do
[{:atadura, "~> 0.1"}]
end
```
## Usage
The module providing easy binding for meta-generated modules. Use it as:
#### Example
```elixir
require Atadura
Atadura.defmodule Circle, answer: 42, pi: 3.14 do
def area(radius: r), do: 2.0 * pi * r
end
Circle.area(radius: 2)
#⇒ 12.56
```
_Drawback:_ the compilation of modules, defined with `Atadura` will generate
warnings like:
warning: variable "status" does not exist and is being expanded to "status()",
please use parentheses to remove the ambiguity or change the variable name
I have no idea yet on how to suppress them, besides using `status()` for
calling binded variables. Sorry for that.
To create a module with bindings, use `Atadura.defmodule` in place of
plain old good `defmodule`. Whatever is passed as second parameter keyword
list, will be available in the generated module in three different ways:
- as local functions,
- as module variables,
- as `~b||` sigil.
The module will be granted with `bindings` function, returning
all the bindings as a keyword list.
Also, a “nested” module will be created for the generated module. It is named
`Parent.Module.FQName.Bindings`, and is exporting following macros:
- `bindings!` to populate the bindings as local variables in the current context
- `attributes!` to populate the bindings as module attributes in the current
context (_NB:_ this macro is internally called to populate module attributes
in the newly created module).
#### Examples
```elixir
defmodule WithBinding do
require Atadura
Atadura.defmodule DynamicModule, status: :ok, message: "¡Yay!" do
def response, do: [status: status, message: message]
IO.inspect message, label: "Message (local)"
#⇒ Message (local): "¡Yay!"
IO.inspect @message, label: "Message (attribute)"
#⇒ Message (attribute): "¡Yay!"
IO.inspect ~b|status message|, label: "Message (sigil)"
#⇒ Message (sigil): [:ok, "¡Yay!"]
end
end
WithBinding.DynamicModule.response()
#⇒ [status: :ok, message: "¡Yay!"]
```
#### Populating attributes:
```elixir
require WithBinding.DynamicModule.Bindings
#⇒ WithBinding.DynamicModule.Bindings
WithBinding.DynamicModule.Bindings.bindings!
#⇒ [:ok, "¡Yay!"]
status
#⇒ :ok
```
## Importing
```elixir
import Atadura, only: [:defmodule, 3]
```
The above allows to still use default `Kernel.defmodule/2` unless
the keyword list is given as the second parameter:
```elixir
import Atadura, only: [:defmodule, 3]
# Plain old good `Kernel.defmodule/2` without bindings
defmodule A1, do: def a, do: IO.puts "★★★"
# `Atadura.defmodule/3` with bindings
defmodule A2, [b: 42], do: def a, do: IO.puts "★★★"
```
Without explicit `import`, `Atadura.defmodule/{2,3}` would gracefully
fallback to `Kernel.defmodule/2` if no bindings were given.
## Changelog
#### 0.2.0 allow dynamic module names
## Documentation
The docs, although everything is written above in this `README`, can
be found at [https://hexdocs.pm/atadura](https://hexdocs.pm/atadura).