# What is a GlobalRef and how I use it?

**URL:** <https://discourse.julialang.org/t/what-is-a-globalref-and-how-i-use-it/90971>\
**Category:** Internals & Design\
**Created:** [November 29, 2022, 12:45am UTC](https://discourse.julialang.org/t/what-is-a-globalref-and-how-i-use-it/90971 "2022-11-29T00:45:52Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lilith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lilith/32/27492_2.png) [@Lilith](https://discourse.julialang.org/u/Lilith)\
**Post date:** [November 29, 2022, 12:45am UTC](https://discourse.julialang.org/t/what-is-a-globalref-and-how-i-use-it/90971/1 "2022-11-29T00:45:52Z")

</div>

# Motivation

RecipesBase.jl defines a macro `@recipe` that adds new methods to the `RecipesBase.apply_recipe` function. The catch is that `RecipesBase` might not be in scope at the macro call site, so the function `RecipesBase.apply_recipe` must be passed in directly.

I first tried interpolation

```julia-auto
:($apply_recipe(x) = x+1)

```

But that failed because functions cannot be interpolated into function declarations. I thaught this was a bug and opened an [issue](https://github.com/JuliaLang/julia/issues/47726), but apparently I’m supposed to be using `GlobalRef`s instead.

I tried this

```julia-auto
:(Expr(:call, GlobalRef(RecipesBase, :apply_recipe), :x) = x+1)

```

But got segfaults on some [downstream tests](https://github.com/JuliaPlots/Plots.jl/actions/runs/3565301737/jobs/5990291002).

Finally, I tried

```julia-auto
:(let M = $RecipesBase
    M.apply_recipe(x) = x+1
end)

```

Which works but seems needlessly complex.

PR: [https://github.com/JuliaPlots/Plots.jl/pull/4559](https://github.com/JuliaPlots/Plots.jl/pull/4559)

# Questions

Why does the second approach above not work? How could it possibly be causing downstream segfaults? Is `GlobalRef` documented anywhere? What is a GlobalRef and how I use it?

---

<div class="post-metadata">

**Author:** ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)\
**Post date:** [November 29, 2022, 8:40am UTC](https://discourse.julialang.org/t/what-is-a-globalref-and-how-i-use-it/90971/2 "2022-11-29T08:40:30Z")

</div>

I don’t know what a `GlobalRef` is and how it would help your problem. But here are (I think) a few ways to solve your problem:

```julia
module Foo
function foo end

# Does not work
macro new_foo_method_v0()
    quote
        $foo(::Val{0}) = 0
    end
end

# Your workaround (IIUC), relying on the module knowing about itself
macro new_foo_method_v1()
    quote
        let M=$Foo
            M.foo(::Val{1}) = 1
        end
    end
end

# The same as above, in a less convoluted way IMO
macro new_foo_method_v2()
    quote
        $Foo.foo(::Val{2}) = 2
    end
end

# Another way, relying only the value of the function (not its name)
macro new_foo_method_v3()
    quote
        (::typeof($foo))(::Val{3}) = 3
    end
end
end

```

Apart from `v0`, which fails as you already know, the other versions work as you’d expect (if I understood your problem correctly)

```julia
julia> Foo.@new_foo_method_v0
ERROR: syntax: invalid function name "Foo.foo" around REPL[1]:7
Stacktrace:
 [1] top-level scope
   @ REPL[2]:1

julia> Foo.@new_foo_method_v1

julia> Foo.@new_foo_method_v2

julia> Foo.@new_foo_method_v3

julia> methods(Foo.foo)
# 3 methods for generic function "foo":
[1] foo(::Val{1}) in Main at REPL[1]:15
[2] foo(::Val{2}) in Main at REPL[1]:23
[3] foo(::Val{3}) in Main at REPL[1]:30

```

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [November 29, 2022, 8:59am UTC](https://discourse.julialang.org/t/what-is-a-globalref-and-how-i-use-it/90971/3 "2022-11-29T08:59:26Z")

</div>

> [@ffevotte](#):
>
> `$Foo.foo(::Val{2}) = 2`

This is the best way in my opinion.

---

<div class="post-metadata">

**Author:** ![Lilith](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lilith/32/27492_2.png) [@Lilith](https://discourse.julialang.org/u/Lilith)\
**Post date:** [November 29, 2022, 10:55am UTC](https://discourse.julialang.org/t/what-is-a-globalref-and-how-i-use-it/90971/4 "2022-11-29T10:55:50Z")

</div>

Thanks! That solves my use case, but I’m still curious about `GlobalRef`s.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [November 29, 2022, 12:56pm UTC](https://discourse.julialang.org/t/what-is-a-globalref-and-how-i-use-it/90971/5 "2022-11-29T12:56:07Z")

</div>

As far as I know, `GlobalRef` is used by the compiler to make variables in local scope refer to objects from the containing global scope. I don’t think there’s too much to “use” here from the high level language, as Simeon mentioned in the issue - they’re emitted by the compiler and need a corresponding mapping in the scope it references.
