2

I am coming from Fortran and I use global vectors of data over the full program. Usually I declare a module:

module xyz   
     real, allocatable :: vector(:,:,:)   ! a 3 dim vector, undefined    
end module  

Now, in some place, let say Subroutine (Function) A, I am allocating memory for it and initialize to some values:

allocate(vector(10,20,30))    
vector = ran()

Now, in any other unit of the program (Subroutine or function B, C, D...), if I am using the module, i.e:

using xyz

The above declared vector is available.

I was not able to obtain this behavior in the new technological wonder Julia 1.1. The scope rules are just giving a headache.

carstenbauer
  • 9,817
  • 1
  • 27
  • 40
  • Please let me know if the explanation is clear; if not I can expand on it. – Bogumił Kamiński Jul 31 '19 at 13:43
  • Be mindful that there are [several reasons to avoid using global variables](https://stackoverflow.com/questions/484635/are-global-variables-bad), so you might want to explore a different approach. – Felipe Lema Aug 01 '19 at 13:48
  • Bogumil -- Thanks for your help. Reading documentation and doing with your hands is different. I figured out that I need both export and global in the defining module, in order to make the variable generally available. – sylvian kahane Aug 01 '19 at 14:07

1 Answers1

4

In Julia the rules for accessing variables from other modules are explained in detail here.

The key issues in your situation are the following things:

  • a variable is visible after using only if it is exported in the module
  • you are allowed to access the variable in other modules
  • you are not allowed to rebind a variable from other modules

This means that global variable binding creation operation is private to the module.

Here is a simple example module definition:

module M

export x

x = Int[]

function rebindx()
    global x = Int[]
end

end

now assume you define and later use it in REPL (it could be any other module)

julia> module M

       export x

       x = Int[]

       function rebindx()
           global x = Int[]
       end

       end
Main.M

julia> using .M

Now you can access x:

julia> x
0-element Array{Int64,1}

julia> push!(x, 1)
1-element Array{Int64,1}:
 1

julia> x
1-element Array{Int64,1}:
 1

julia> x[1] = 10
10

julia> x
1-element Array{Int64,1}:
 10

But not rebind x:

julia> x = 0
ERROR: cannot assign variable M.x from module Main

However, you can call a function defined inside M module to change the binding of x like this:

julia> x
1-element Array{Int64,1}:
 10

julia> M.rebindx()
0-element Array{Int64,1}

julia> x
0-element Array{Int64,1}

This was possible because rebindx was defined inside module M so it has the right to change the binding of variable x defined in this module.

Bogumił Kamiński
  • 66,844
  • 3
  • 80
  • 107