# Is there a way to define a 'module' variable?

**URL:** <https://discourse.julialang.org/t/is-there-a-way-to-define-a-module-variable/55301>\
**Category:** New to Julia\
**Created:** [February 15, 2021, 8:57am UTC](https://discourse.julialang.org/t/is-there-a-way-to-define-a-module-variable/55301 "2021-02-15T08:57:20Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![stefkuypers](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefkuypers/32/19185_2.png) [@stefkuypers](https://discourse.julialang.org/u/stefkuypers)\
**Post date:** [February 15, 2021, 8:57am UTC](https://discourse.julialang.org/t/is-there-a-way-to-define-a-module-variable/55301/1 "2021-02-15T08:57:20Z")

</div>

I’m struggling a bit with scopes.

From the documentation, this works:

```julia
module Bar
       x = 1
       foo() = x
       export foo
end

using .Bar
foo()

```

But this does not:

```julia
module Tofu
       counter = 0
       f() = (counter += 1; counter)
       export f
end

using .Tofu
f()

```

The latter gives me a ‘counter not defined’ error.

I’m guessing this is an implementation thing. My guess is that the compiler binds 1 to f() in the first example so x is actually never referenced in the call to f(). But from a coding perspective this makes no sense since the first and second example should produce similar results from that perspective.

Is there a way to define a variable which is accessible within the module but not outside it except when it is explicitly referenced?

Thanks in advance,  
Stef

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [February 15, 2021, 9:18am UTC](https://discourse.julialang.org/t/is-there-a-way-to-define-a-module-variable/55301/2 "2021-02-15T09:18:47Z")

</div>

I’ll leave the why to someone else but this is what you need to do:

```julia
module Tofu
       counter = 0
       f() = (global counter += 1; counter)
       export f
end

```

---

<div class="post-metadata">

**Author:** ![pixel27](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pixel27/32/8902_2.png) [@pixel27](https://discourse.julialang.org/u/pixel27)\
**Post date:** [February 16, 2021, 3:27pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-define-a-module-variable/55301/3 "2021-02-16T15:27:19Z")

</div>

> [@stefkuypers](#):
>
> I’m guessing this is an implementation thing. My guess is that the compiler binds 1 to f() in the first example so x is actually never referenced in the call to f().

Nope, you can test that by:

```julia
julia> module Bar
              x = 1
              foo() = x
              x= 2
              export foo
       end
Main.Bar

julia> using .Bar

julia> foo()
2

```

I believe the issue is that the parentheses are creating a local context, so `counter` is expected to be local. With @GunnarFarneback’s fix the `global` keyword tells the compiler that `counter` is global. (It’s a subtly push to keep people from using global variables, as they don’t perform as well as local variables.)

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [February 16, 2021, 4:00pm UTC](https://discourse.julialang.org/t/is-there-a-way-to-define-a-module-variable/55301/4 "2021-02-16T16:00:45Z")

</div>

I think you are just seeing the normal scope behaviour, but inside a module:

```julia
julia> x = 1
1

julia> function f()
          x = x + 1
       end
f (generic function with 1 method)

julia> f()
ERROR: UndefVarError: x not defined
Stacktrace:
 [1] f() at ./REPL[2]:2
 [2] top-level scope at REPL[3]:1

julia> function f()
          x + 1
       end
f (generic function with 1 method)

julia> f()
2

julia> function f()
         global x = x + 1
       end
f (generic function with 1 method)

julia> f()
2

```

Meaning: if you want to reassign the value of a global variable inside a function, you need to explicitly mention that it is global. (I had to think how phrase this, because the ambiguity exists only when one tries to _use_ and _assign_ the same label in the same expression. Otherwise one is just assigning a new label to a new value, or using the value of the global variable).

Where the behaviour is different in the REPL and in a module is with loops:

```julia
julia> module M
         x = 1
         for i in 1:3
           x = x + 1
         end
       end
ERROR: UndefVarError: x not defined
Stacktrace:
 [1] top-level scope at ./REPL[15]:4

julia> x = 1 
1

julia> for i in 1:3
         x = x + 1
       end

julia> x
4

julia> module M
         x = 1
         for i in 1:3
           global x = x + 1
         end
       end
WARNING: replacing module M.
Main.M

julia> M.x
4

```

Maybe when someone does that inside a module we should return the same good warning/error message that one gets when one tries to do that in a file?

```julia
julia> include("./mod.jl")
┌ Warning: Assignment to `x` in soft scope is ambiguous because a global variable by the same name exists: `x` will be treated as a new local. Disambiguate by using `local x` to suppress this warning or `global x` to assign to the existing global variable.
└ @ ~/Drive/Work/JuliaPlay/mod.jl:3
ERROR: LoadError: UndefVarError: x not defined

```

(not that I see many use cases for a loop that is executed on module loading)
