# Runtime arguments for \_\_init\_\_?

**URL:** https://discourse.julialang.org/t/runtime-arguments-for-init/101170
**Category:** General Usage
**Tags:** module
**Created:** [July 4, 2023, 1:25pm UTC](https://discourse.julialang.org/t/runtime-arguments-for-init/101170 "2023-07-04T13:25:32Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![alan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alan/32/15970_2.png) [@alan](https://discourse.julialang.org/u/alan)
#### Post date: [July 4, 2023, 1:25pm UTC](https://discourse.julialang.org/t/runtime-arguments-for-init/101170/1 "2023-07-04T13:25:32Z")

</div>

I thought at first that this was a general way to write an application that would be precompiled and would therefore load fast. However, I think I see a problem. There seems to be no way to pass arguments to a module’s ` __init__ ` function. Consequently, ` __init__ ()` can’t be controlled by command-line arguments. Is there a way around this problem?

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [July 4, 2023, 1:29pm UTC](https://discourse.julialang.org/t/runtime-arguments-for-init/101170/2 "2023-07-04T13:29:56Z")

</div>

> [@alan](#):
>
> There seems to be no way to pass arguments to a module’s ` __init__ ` function. Consequently, ` __init__ ()` can’t be controlled by command-line arguments. Is there a way around this problem?

Why do you need to pass arguments to ` __init__ `? (As opposed to passing arguments at runtime to a function in the module from a script that calls the module?)

(You can modify the behavior of ` __init__ ` at runtime with environment variables, for example. But probably you just want to make ` __init__ ` do less and put the runtime functionality into ordinary functions.)

---

<div class="post-metadata">

### Author: ![alan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alan/32/15970_2.png) [@alan](https://discourse.julialang.org/u/alan)
#### Post date: [July 4, 2023, 1:39pm UTC](https://discourse.julialang.org/t/runtime-arguments-for-init/101170/3 "2023-07-04T13:39:02Z")

</div>

The goal is to get the code to precompile so it will load quickly. In an answer to my original question, user “mkitti” showed how to implement “Hello world” within ` __init__ ` in order to take advantage of the automatic precompilation of modules. I’m trying to figure out whether this approach can be generalized. For example, could one use this approach to rewrite the Unix “echo” command?

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [July 4, 2023, 1:49pm UTC](https://discourse.julialang.org/t/runtime-arguments-for-init/101170/4 "2023-07-04T13:49:33Z")

</div>

What you would normally do would be to put _most_ of your code into a precompiled module/package, but then to write a short script that merely loads and calls your module. This short script is what parses e.g. command-line arguments (or runs interactively, as in a Jupyter or Pluto notebook).

---

<div class="post-metadata">

### Author: ![alan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alan/32/15970_2.png) [@alan](https://discourse.julialang.org/u/alan)
#### Post date: [July 4, 2023, 1:47pm UTC](https://discourse.julialang.org/t/runtime-arguments-for-init/101170/5 "2023-07-04T13:47:56Z")

</div>

On reflection, I think you’re right. The obvious approach would be to write an “echo” function within the module, which would take arguments.

No further questions. Thanks for the help.

---

<div class="post-metadata">

### Author: ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)
#### Post date: [July 4, 2023, 5:01pm UTC](https://discourse.julialang.org/t/runtime-arguments-for-init/101170/6 "2023-07-04T17:01:28Z")

</div>

Let me start with a minimal example that emulates `echo`. The `ARGS` global constant contains command line arguments. It is a `Vector{String}`.

Here is Echo.jl.

```julia
module Echo
    __init__ () = println(join(ARGS, " "))
end

```

Here is a demo.

```julia
$ julia Echo.jl This is a test
This is a test

$ julia Echo.jl "This is another test." "Hello world"
This is another test. Hello world

```

stevengj, I usually write all my scripts as modules so their accessory functions can used elsewhere.

Here is an expanded Echo.jl.

```julia
module Echo
    function __init__ ()
        @debug "Globals" PROGRAM_FILE @ __FILE__ () ARGS
        if !Base.isinteractive() && @ __FILE__ () == abspath(PROGRAM_FILE)
            # We are directly executing this file from the command line
            main()
        end
    end
    main() = echo(ARGS)
    echo(args) = println(join(args, " "))
end

```

We see that the program still works. Additionally, we can now print some debugging information.

```julia
$ julia Echo.jl Hello alan and stevengj
Hello alan and stevengj

$ JULIA_DEBUG=Echo julia Echo.jl Hello alan and stevengj
┌ Debug: Globals
│ PROGRAM_FILE = "Echo.jl"
│ #= /home/mkitti/Echo.jl:3 =# @ __FILE__ = "/home/mkitti/Echo.jl"
│ ARGS =
│ 4-element Vector{String}:
│ "Hello"
│ ⋮
└ @ Main.Echo ~/Echo.jl:3
Hello alan and stevengj

```

I can also interact with this file from the Julia REPL.

```julia
$ julia --banner=no -i Echo.jl This is a test
julia> Echo.main()
This is a test

julia> Echo.echo(["I am calling this from", "the Julia REPL"])
I am calling this from the Julia REPL

```

The above is a fancy script that I can run, include, and debug. While there is some compilation happening in memory, it is not being cached to disk.

```julia
s ~/.julia/compiled/v1.9/Echo
ls: cannot access '/home/mkitti/.julia/compiled/v1.9/Echo': No such file or directory

```

Let’s restructure the program so that it is precompiled.

We organize a project simliar to before.

```julia
$ tree -p src/Echo.jl
[drwxrwxr-x] src/Echo.jl
├── [-rw-rw-r--] Project.toml
├── [drwxrwxr-x] scripts
│ └── [-rwxrwxr-x] echo.jl
└── [drwxrwxr-x] src
    └── [-rw-rw-r--] Echo.jl

$ cat src/Echo.jl/Project.toml 
name = "Echo"
uuid = "594283f3-b8da-40eb-8bd5-2e27980f0e39"

$ cat src/Echo.jl/scripts/echo.jl 
#!/bin/env julia
using Pkg
if length(ARGS) > 0 && ARGS[1] == "-q"
    io = devnull
    popfirst!(ARGS)
else
    io = stdout
end
Pkg.activate(
    @ __FILE__ () |>
    x->(islink(x) ? readlink(x) : x) |>
    dirname |>
    dirname
    ; io
)

using Echo

$ cat src/Echo.jl/src/Echo.jl 
module Echo
    const EXE = abspath(joinpath(@ __FILE__ , "..", "..", "scripts", "echo.jl"))
    function __init__ ()
        @debug "Globals" PROGRAM_FILE EXE ARGS ismain()
        # Run main if we are executing $EXE from the command line
        ismain() && main()
    end
    function ismain(executable=EXE)
        Base.isinteractive() && return false
        program_file = abspath(PROGRAM_FILE)
        while islink(program_file)
            program_file = readlink(program_file)
        end
        @debug "ismain" executable program_file
        return executable == program_file
    end
    main() = echo(ARGS)
    echo(args) = println(join(args, " "))
end

```

Now we can try installing the script in `~/bin` and running it.

```julia
$ ln -s ~/src/Echo.jl/scripts/echo.jl ~/bin/

$ echo.jl This is a test. Hello world!
  Activating project at `~/src/Echo.jl`
This is a test. Hello world!

$ echo.jl -q Quieter please.
Quieter please.

```

We also see that the code has been precompiled.

```julia
$ ls ~/.julia/compiled/v1.9/Echo/
5n5AW_0ml5H.ji 5n5AW_0ml5H.so

```

To be honest, for a simple script like this, I might not bother with all of this machinery. Frankly, I mostly do this while deploying this code for other people.

---

<div class="post-metadata">

### Author: ![alan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alan/32/15970_2.png) [@alan](https://discourse.julialang.org/u/alan)
#### Post date: [July 4, 2023, 9:52pm UTC](https://discourse.julialang.org/t/runtime-arguments-for-init/101170/7 "2023-07-04T21:52:07Z")

</div>

That was very helpful. Thank you.
