# `Mob.InitArgs`
[🔗](https://github.com/genericjam/mob/blob/master/lib/mob/init_args.ex#L1)

Erlang init arguments the app chooses for its own next launch.

The native launcher (`mob_beam.zig` on Android, `mob_beam.m` on iOS) reads
`$MOB_DATA_DIR/mob_init_args` at startup and appends its tokens to the BEAM's
init arguments, after the second `--` and after mob's own (`-noshell` …
`-eval`), in development **and release** builds. This is where flags such as
`-proto_dist` and `-ssl_dist_optfile` belong: they are init arguments, which
the emulator rejects in the emulator-flag section that
`beams_dir/mob_beam_flags` (written by `mix mob.deploy --beam-flags`) feeds.

    Mob.InitArgs.write(["-proto_dist", "inet_tls", "-ssl_dist_optfile", path])

Things to know:

  * **It takes effect at the next launch.** The running BEAM already parsed
    its arguments; see `:init.get_arguments/0` for the ones this launch got.
  * **A bad argument can stop the BEAM from booting**, and then no Elixir
    code runs to undo it: only clearing the app's data or reinstalling does.
    Only write flags you understand. Distribution flags also reopen a
    network listener in release builds; authenticate and encrypt it.
  * The launcher's limits: 1023 bytes for the whole file and 63
    arguments. It keeps whole arguments up to the limit, logs, and
    drops the rest; `write/1` refuses lists over either limit instead.
  * Arguments are split on whitespace and can't be quoted, so a single
    argument can't contain a space; `write/1` refuses one that does.
  * On iOS, an argument list containing `-name` or `-sname` makes the
    launcher leave out mob's own development distribution flags (`-name`,
    `-setcookie`, the `inet_dist_*` kernel settings): the app owns
    distribution, and `mix mob.connect` won't find the node under mob's name.
    Release builds never add mob's development flags, but app arguments
    still apply and may intentionally start distribution. Android starts
    mob's development distribution at runtime (see `Mob.Dist`).

# `reason`

```elixir
@type reason() ::
  :no_data_dir
  | {:invalid_arg, term()}
  | {:too_many_args, non_neg_integer()}
  | {:too_large, non_neg_integer()}
  | File.posix()
```

# `clear`

```elixir
@spec clear() :: :ok
```

Removes the file, so the next launch gets only mob's own arguments.

# `path`

```elixir
@spec path() :: String.t() | nil
```

The file the launcher reads, or `nil` when `MOB_DATA_DIR` is unset (off
device, where no launcher reads it).

# `read`

```elixir
@spec read() :: [String.t()]
```

The tokens currently represented by the file, or `[]` when it is absent.
Files produced by `write/1` are exactly what the next launch receives.
A hand-edited file beyond the documented limits may be truncated by the
native launcher even though `read/0` returns all of its tokens.

# `write`

```elixir
@spec write([String.t()]) :: :ok | {:error, reason()}
```

Replaces the arguments for the next launch. `write([])` removes the file.

Every argument must be a non-empty binary without whitespace or NUL, and the
list must fit the launcher's limits (see the moduledoc); otherwise nothing is
written. The file is replaced atomically, so a launch never reads half of it.

---

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