# Sub module accessing a global method

**URL:** https://discourse.julialang.org/t/sub-module-accessing-a-global-method/22652
**Category:** General Usage
**Tags:** question
**Created:** [April 2, 2019, 7:26pm UTC](https://discourse.julialang.org/t/sub-module-accessing-a-global-method/22652 "2019-04-02T19:26:13Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![iPostHuman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iposthuman/32/7463_2.png) [@iPostHuman](https://discourse.julialang.org/u/iPostHuman)
#### Post date: [April 2, 2019, 7:26pm UTC](https://discourse.julialang.org/t/sub-module-accessing-a-global-method/22652/1 "2019-04-02T19:26:13Z")

</div>

I am fairly new to **Julia** 😉

My question centers around a sub-module trying to call a method (_not a function_) where the method is in global space. I have a module named `Nodes` that wants to call a method `transition(...)`. `transition(...)` exists within the global namespace yet Julia throws because it can’t find the method. I thought if a method was in the global space it was accessible from all modules without requiring imports.

The error below I get doesn’t seem to make sense to me:

```julia
ERROR: LoadError: MethodError: no method matching transition(::SplashScene)
Closest candidates are:
  transition(!Matched::Main.Ranger.Nodes.Scenes.SceneBoot) at /home/iposthuman/Documents/Development/Julia/Source/Ranger-Julia-SDL/nodes/scenes/scene_boot.jl:36
Stacktrace:
 [1] visit(::NodeManager, ::Float64) at /home/iposthuman/Documents/Development/Julia/Source/Ranger-Julia-SDL/nodes/node_manager.jl:74
 [2] run(::World) at /home/iposthuman/Documents/Development/Julia/Source/Ranger-Julia-SDL/game/game.jl:111
 [3] go() at /home/iposthuman/Documents/Development/Julia/Source/Ranger-Julia-SDL/examples/template0/main.jl:18
 [4] top-level scope at none:0
 [5] include at ./boot.jl:326 [inlined]
 [6] include_relative(::Module, ::String) at ./loading.jl:1038
 [7] include(::Module, ::String) at ./sysimg.jl:29
 [8] exec_options(::Base.JLOptions) at ./client.jl:267
 [9] _start() at ./client.jl:436
in expression starting at /home/iposthuman/Documents/Development/Julia/Source/Ranger-Julia-SDL/examples/template0/main.jl:22

```

Julia sees one of the methods `transition(..SceneBoot)` because I can import it:

```julia
using .Scenes:
    AbstractScene,
    enter_node, transition,
    REPLACE_TAKE

```

Yet `varinfo()` shows the `transition` method is present:

```julia
name size summary                
–––––––––––––––– ––––––––––– –––––––––––––––––––––––
Base Module                 
Core Module                 
GameScene 196 bytes DataType               
InteractiveUtils 163.926 KiB Module                 
Main Module                 
RAnim 6.567 KiB Module                 
RGame 23.112 KiB Module                 
RGeo 11.195 KiB Module                 
RMath 22.614 KiB Module                 
RNodes 33.537 KiB Module                 
RRendering 22.289 KiB Module                 
RScenes 10.746 KiB Module                 
Ranger 123.143 KiB Module                 
SplashScene 196 bytes DataType               
ans 0 bytes Nothing                
build 0 bytes typeof(build)          
enter_node 0 bytes typeof(enter_node)     
exit_node 0 bytes typeof(exit_node)      
get_replacement 0 bytes typeof(get_replacement)
go 0 bytes typeof(go)             
transition 0 bytes typeof(transition)  
visit 0 bytes typeof(visit)  

```

And running `methods` on `transition` clearly shows that a matching method exists for `transition(..SplashScene)`:

```julia
julia> methods(transition)
# 2 methods for generic function "transition":
[1] transition(node::GameScene) in Main at /home/iposthuman/Documents/Development/Julia/Source/Ranger-Julia-SDL/examples/template0/game_scene.jl:56
[2] transition(node::SplashScene) in Main at /home/iposthuman/Documents/Development/Julia/Source/Ranger-Julia-SDL/examples/template0/splash_scene.jl:53

```

This leads me to think I need to _import_ —somehow— into my Nodes module from Main.

My modules are arranged as follows:

```julia
Ranger <== top module as shown above
  Nodes <== aliased via a const as RNodes

```

`Nodes` module has a function called `visit(...)` inside the file **node\_manager.jl**

```julia
function visit(man::NodeManager, interpolation::Float64)
    if is_empty(man.stack)
        println("NodeManager: no more nodes to visit.")
        return false
    end
    ... some stuff
    # If mouse coords changed then update view coords.
    # self.global_data.update_view_coords(&mut self.context);
    println("Transition..........")
    action = transition(man.stack.running_node) <===== transition isn't found????
    println("action ", action)

    ... more stuff
    true # continue to draw.
end

```

My question is: how do I make the `transition` method(s) visible to `visit`? I feel fairly comfortable applying `using` and `import` but I could be missing something. At this point I am scratching my head trying to figure out what Julia expects.

The source is available at:  
[Ranger Julia](https://github.com/wdevore/Ranger-Julia-SDL)

Any ideas or thoughts?

Thanks.

---

<div class="post-metadata">

### Author: ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)
#### Post date: [April 2, 2019, 8:07pm UTC](https://discourse.julialang.org/t/sub-module-accessing-a-global-method/22652/2 "2019-04-02T20:07:51Z")

</div>

This is a lot of code to try to understand all at once, but I think I can make a guess as to what is going on. I suspect you are doing something like this:

```julia
julia> module Outer
         export f
         f(::Int) = 1

         module Inner
           using ..Outer
           f(::Float64) = 2 # BAD: this is *not* a new method for Outer.f, but instead a brand-new function with the same name.
           
           f(1) # this fails because Inner.f is a function with just one method: f(::Float64).
         end
       end
WARNING: replacing module Outer.
ERROR: MethodError: no method matching f(::Int64)
Closest candidates are:
  f(::Float64) at REPL[7]:7

```

Instead, you need to explicitly extend the method from the other module, just as you do with all other methods in Julia:

```julia
julia> module Outer
         export f
         f(::Int) = 1

         module Inner
           using ..Outer
           Outer.f(::Float64) = 2 # GOOD: we are explicitly adding a new method to Outer.f, not making a new function with the same name
           @show f(1) f(1.0) # this works!
         end
       end
WARNING: replacing module Outer.
f(1) = 1
f(1.0) = 2

```

Alternatively, instead of:

```julia
using ..Outer
Outer.f(...) = ...

```

you could also have done:

```julia
import ..Outer: f
f(...) = ...

```

which has the same effect.

The presence of nested modules doesn’t affect the behavior of this at all: you will experience the same issue regardless of whether `Inner` happens to live inside `Outer` or not.

---

<div class="post-metadata">

### Author: ![iPostHuman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iposthuman/32/7463_2.png) [@iPostHuman](https://discourse.julialang.org/u/iPostHuman)
#### Post date: [April 3, 2019, 2:41am UTC](https://discourse.julialang.org/t/sub-module-accessing-a-global-method/22652/3 "2019-04-03T02:41:16Z")

</div>

Interesting. But what if the “outer” isn’t in a custom module but a method within Main? Your example gave me the clue I needed—Nice! And! I also learned from your example how to override a function using an explicit semantics—thanks.

In addition, I reduced my code down to an example similar to yours. What I was confused 🤔 about was importing from `Main` and I finally figured it out as shown below:

```julia
function transition(f::Float64)
  println(f)
end

function transition(i::UInt32)
  println(i)
end

module Ranger
  module Nodes
    using Main:transition # <-- This is what I needed
    
    function visit()
      transition(1.0)
      transition(UInt32(3))
    end
  end
end

module Game
  using ..Ranger.Nodes:
    visit
    
  function run()
    visit()
  end
end

using .Game:
  run
  
function go()
  run()
end
  
go()

```

Now that I think about I could just make sure my Scenes are within a well defined module, for example `GameInstance`, and then have my engine expect that module to exist. 🤔

Update: After looking at my code I realized I am in a chicken and egg scenario. My game constructs only after the engine construct, however, the engine is trying to import methods from the game construction.

```julia

include("../../ranger.jl") # <-- Chicken

const RGame = Ranger.Game

include("build.jl") # <-- Egg!

using .Ranger.Game:
    World

println("Running Template 0")

function go()
    world = RGame.initialize("Template 0", build)

    RGame.run(world);
end

```

Argh! Why doesn’t Julia have the ability to forward-declare. It would be nice if Julia had a Block type include that allow all code to parse prior to cross checking dependencies.

How do I get myself out of this conundrum? 🤨

Thanks rdeits.

---

<div class="post-metadata">

### Author: ![iPostHuman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iposthuman/32/7463_2.png) [@iPostHuman](https://discourse.julialang.org/u/iPostHuman)
#### Post date: [April 4, 2019, 7:47pm UTC](https://discourse.julialang.org/t/sub-module-accessing-a-global-method/22652/4 "2019-04-04T19:47:10Z")

</div>

This issue is resolved. Please see this related question:

[How do I add a function/method to an already defined module](https://discourse.julialang.org/t/how-do-i-add-a-function-method-to-an-already-defined-module/22699/7)
