# `Dune.Session`
[🔗](https://github.com/functional-rewire/dune/blob/v0.3.18/lib/dune/session.ex#L1)

Sessions provide a way to evaluate code and keep state (bindings, modules...) between evaluations.

- Use `Dune.eval_string/2` to execute code as a one-off
- Use `Dune.Session.eval_string/3` to execute consecutive code blocks

`Dune.Session` could be used to implement something like a safe IEx shell, or to compile a module
once and call it several times without the overhead of parsing.

`Dune.Session` is also a struct that is used to store the state of an evaluation.

Only the following fields are public:
- `last_result`: contains the result of the last evaluation, or `nil` for empty sessions

Other fields are private and shouldn't be accessed directly.

# `private_compile_env`

```elixir
@opaque private_compile_env()
```

# `private_env`

```elixir
@opaque private_env()
```

# `t`

```elixir
@type t() :: %Dune.Session{
  bindings: keyword(),
  compile_env: private_compile_env(),
  env: private_env(),
  last_result: nil | Dune.Success.t() | Dune.Failure.t()
}
```

The type of a `Dune.Session`.

# `eval_string`

```elixir
@spec eval_string(t(), String.t(), keyword()) :: t()
```

Evaluates the provided `string` in the context of the `session` and returns a new session.

The result will be available in the `last_result` key.
In case of a success, the variable bindings or created modules will be saved in the session.
In case of a failure, the rest of the session state won't be updated, so it is possible to
keep executing instructions after a failure

## Examples

    iex> Dune.Session.new()
    ...> |> Dune.Session.eval_string("x = 1")
    ...> |> Dune.Session.eval_string("x + 2")
    #Dune.Session<last_result: %Dune.Success{value: 3, inspected: "3", stdio: ""}, ...>

    iex> Dune.Session.new()
    ...> |> Dune.Session.eval_string("x = 1")
    ...> |> Dune.Session.eval_string("x = x / 0")  # will fail, but the previous state is kept
    ...> |> Dune.Session.eval_string("x + 2")
    #Dune.Session<last_result: %Dune.Success{value: 3, inspected: "3", stdio: ""}, ...>

# `new`

```elixir
@spec new() :: t()
```

Returns a new empty session.

## Examples

    iex> Dune.Session.new()
    #Dune.Session<last_result: nil, ...>

---

*Consult [api-reference.md](api-reference.md) for complete listing*
