# Sharing a package global dictionary with other packages

**URL:** https://discourse.julialang.org/t/sharing-a-package-global-dictionary-with-other-packages/97326
**Category:** General Usage
**Created:** [April 11, 2023, 4:46am UTC](https://discourse.julialang.org/t/sharing-a-package-global-dictionary-with-other-packages/97326 "2023-04-11T04:46:37Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![ablaom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ablaom/32/4889_2.png) [@ablaom](https://discourse.julialang.org/u/ablaom)
#### Post date: [April 11, 2023, 4:46am UTC](https://discourse.julialang.org/t/sharing-a-package-global-dictionary-with-other-packages/97326/1 "2023-04-11T04:46:37Z")

</div>

I want to define a dictionary in one package that other client packages can access and update. For a proof of concept, let’s define a “base” module `Foo` and a client module `Bar`:

```julia
# module `Foo` defines a global dictionary and methods to add or recall it:

module Foo

const DICT = Dict()

println("resetting DICT.")
dict() = DICT

function add(item)
    println("adding $item")
    DICT[item] = string(item)
end

add(:foo_item)

end

# module `Bar` imports `Foo` and adds to the dictionary

module Bar
import ..Foo: add, dict
export dict, add

add(:bar_item)

end

```

Then I get the following expected behaviour:

```julia
using .Bar

dict()
# Dict{Any, Any} with 2 entries:
# :foo_item => "foo_item"
# :bar_item => "bar_item"

add(:main_item)
# adding main_item
# "main_item"

dict()
# Dict{Any, Any} with 3 entries:
# :foo_item => "foo_item"
# :main_item => "main_item"
# :bar_item => "bar_item"

```

However, if I turn `Foo` and `Bar` into packages, then new behaviour emerges:

```julia
julia> using Bar
[Info: Precompiling Bar [84147f7a-2164-45cb-9498-7c2329c08b93]
resetting DICT.
adding foo_item
adding bar_item

dict()
# Dict{Any, Any} with 1 entry:
# :foo_item => "foo_item"

```

Where has the `:bar_item` gone? It seems the dictionary has been reset at some point after `Bar` adds to it, but I never see that reflected in the logging I’ve put in.

What do I need to add to my mental model to explain why packages don’t behave like modules? And, what’s the right way to do something like this?

I am not using Revise.jl here.

---

<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: [April 11, 2023, 5:37am UTC](https://discourse.julialang.org/t/sharing-a-package-global-dictionary-with-other-packages/97326/2 "2023-04-11T05:37:04Z")

</div>

You probably want to read the docstring for ` __init__ ` and/or [Modules · The Julia Language](https://docs.julialang.org/en/v1/manual/modules/#Module-initialization-and-precompilation).

---

<div class="post-metadata">

### Author: ![thautwarm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thautwarm/32/37760_2.png) [@thautwarm](https://discourse.julialang.org/u/thautwarm)
#### Post date: [April 11, 2023, 5:47am UTC](https://discourse.julialang.org/t/sharing-a-package-global-dictionary-with-other-packages/97326/3 "2023-04-11T05:47:14Z")

</div>

You have hit the issues (or bless?) of precompilation.

Julia packages are precompiled independently. Global variables are deserialized from precompile cache per package, so modifying them does not work.

Sharing global variables and modifying their contents is not do-able in Julia. In short, just initialize and modify your collections in Julia module’s ` __init__ ` methods. These ` __init__ ` methods correspond to Python files’ toplevel statements.

```julia

########################
## Foo.jl package

module Foo

const DICT = Dict()

dict() = DICT

// ...

function __init__ ()
    # runtime statements here
    empty!(DICT)
end
end # module

########################
## Bar.jl package

module Bar
  export dict
  import Foo: add, dict

   function __init__ ()
      # runtime statements here
      add(:foo_item)
   end
end # end module

########################
## Main

using Bar

dict()

# Dict{Any, Any} with 2 entries:
# :foo_item => "foo_item"
# :bar_item => "bar_item"

```

P.S: If you feel strange, you’d better get to know the point that “the time of executing Julia modules’ toplevel statements could correspond to the time of expanding C++ templates”. You shouldn’t expect static variables created by C++ templates can be modified in other compilation units.

---

<div class="post-metadata">

### Author: ![ablaom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ablaom/32/4889_2.png) [@ablaom](https://discourse.julialang.org/u/ablaom)
#### Post date: [April 11, 2023, 9:08pm UTC](https://discourse.julialang.org/t/sharing-a-package-global-dictionary-with-other-packages/97326/4 "2023-04-11T21:08:07Z")

</div>

Thank you @GunnarFarneback and @thautwarm. I understand now.
