# Scope Question (Maybe Bug?)

**URL:** <https://discourse.julialang.org/t/scope-question-maybe-bug/50500>\
**Category:** General Usage\
**Tags:** scope\
**Created:** [November 20, 2020, 3:05pm UTC](https://discourse.julialang.org/t/scope-question-maybe-bug/50500 "2020-11-20T15:05:17Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Brad\_Carman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brad_carman/32/17631_2.png) [@Brad\_Carman](https://discourse.julialang.org/u/Brad_Carman)\
**Post date:** [November 20, 2020, 3:05pm UTC](https://discourse.julialang.org/t/scope-question-maybe-bug/50500/1 "2020-11-20T15:05:17Z")

</div>

I have an example that has me confused about scope. I define a variable `current_header` which is inside a `for loop`. My understanding is this variable should be in the scope of the `for loop`. Furthermore this example works when running in the Debugger, but not in plain Julia. Here is the code:

scope\_question.jl

```julia
using Debugger

struct FilePart
    header::String
    key::String
    value::String
end

function processfile(lines::Vector{String})
    file = FilePart[]

    for line in lines
        if startswith(line, "[") & endswith(line, "]")
            current_header = line

            println("Header: $current_header")
        else
            parts = split(line, "=")
            key = strip(parts[1])
            value = strip(parts[2])

            println("key: $key | value: $value")

            push!(file, FilePart(current_header, key, value))
        end
    end

    print("finished with $(size(file,1)) values")
    return file
end

lines = [
    "[Test]"
    "key1=value1"
    ]

println("Running in Debugger...")
@run processfile(lines)
println("*")

println()
println("Running Outside Debugger...")
processfile(lines)
println("*")

```

And the output I get is:

> julia\> include(“scope\_question.jl”)  
> Running in Debugger…  
> Header: [Test]  
> key: key1 | value: value1  
> finished with 1 values\*
> 
> Running Outside Debugger…  
> Header: [Test]  
> key: key1 | value: value1  
> ERROR: LoadError: UndefVarError: current\_header not defined

As can be seen I get an UndefVarError for `current_header`. What am I missing about scope here?

---

<div class="post-metadata">

**Author:** ![Brad\_Carman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brad_carman/32/17631_2.png) [@Brad\_Carman](https://discourse.julialang.org/u/Brad_Carman)\
**Post date:** [November 20, 2020, 3:18pm UTC](https://discourse.julialang.org/t/scope-question-maybe-bug/50500/3 "2020-11-20T15:18:47Z")

</div>

But why? As I understand a `for loop` has a scope and `current_header` is defined in that scope. So when I attempt to use it in the same `for loop` shouldn’t it be defined?

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [November 20, 2020, 3:21pm UTC](https://discourse.julialang.org/t/scope-question-maybe-bug/50500/4 "2020-11-20T15:21:14Z")

</div>

It doesn’t have to be global (in fact, it shouldn’t be!), but it has to be defined outside the loop. The reason is that each iteration of a for loop is wrapped in a `let` block. The variables defined inside it exist only until the end of the iteration.

---

<div class="post-metadata">

**Author:** ![FedericoStra](https://avatars.discourse-cdn.com/v4/letter/f/76d3ee/32.png) [@FedericoStra](https://discourse.julialang.org/u/FedericoStra)\
**Post date:** [November 20, 2020, 3:23pm UTC](https://discourse.julialang.org/t/scope-question-maybe-bug/50500/5 "2020-11-20T15:23:10Z")

</div>

From [Scope of Variables · The Julia Language](https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Loops-and-Comprehensions:)

> In loops and [comprehensions](https://docs.julialang.org/en/v1/manual/arrays/#man-comprehensions), new variables introduced in their body scopes are freshly allocated for each loop iteration, as if the loop body were surrounded by a `let` block.

This will not work for instance

```julia
function foo()
    for i in 1:5
        if i == 1
            x = 42
        else
            @show x
        end
    end
end

```

---

<div class="post-metadata">

**Author:** ![Brad\_Carman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brad_carman/32/17631_2.png) [@Brad\_Carman](https://discourse.julialang.org/u/Brad_Carman)\
**Post date:** [November 20, 2020, 3:23pm UTC](https://discourse.julialang.org/t/scope-question-maybe-bug/50500/6 "2020-11-20T15:23:20Z")

</div>

Ah, OK, thank you @tomerarnon!

Do you know why it works in Debugger.jl? Just curious.

---

<div class="post-metadata">

**Author:** ![Brad\_Carman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brad_carman/32/17631_2.png) [@Brad\_Carman](https://discourse.julialang.org/u/Brad_Carman)\
**Post date:** [November 20, 2020, 3:25pm UTC](https://discourse.julialang.org/t/scope-question-maybe-bug/50500/7 "2020-11-20T15:25:59Z")

</div>

Thanks @FedericoStra, I missed that part of the documentation.

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [November 20, 2020, 3:26pm UTC](https://discourse.julialang.org/t/scope-question-maybe-bug/50500/8 "2020-11-20T15:26:07Z")

</div>

No, I don’t honestly. Debugger works differently than normal execution (using an interpreter in many places) and maybe defines it’s own scope with its own variables. It’s worth checking if that behavior has been reported there already, and if not filing an issue.

---

<div class="post-metadata">

**Author:** ![FedericoStra](https://avatars.discourse-cdn.com/v4/letter/f/76d3ee/32.png) [@FedericoStra](https://discourse.julialang.org/u/FedericoStra)\
**Post date:** [November 20, 2020, 3:31pm UTC](https://discourse.julialang.org/t/scope-question-maybe-bug/50500/9 "2020-11-20T15:31:34Z")

</div>

The most obvious approach is to simply declare `x` in the scope of the function:

```julia
function foo()
    local x
    for i in 1:5
        if i == 1
            x = 42
        else
            @show x
        end
    end
end

```

> **Edit: here is the previous version of my answer, which contains a wrong statement caused by some kind of hallucinations I must have had while staring at the REPL for too long.**
>
> What I find less than desirable is that to make my example work one needs to write something like
> 
> ```julia
> function foo()
> x = 0
> for i in 1:5
> if i == 1
> x = 42
> else
> @show x
> end
> end
> end
> 
> ```
> 
> The most obvious approach of simply declaring `x` in the scope of the function
> 
> ```julia
> function foo()
> local x
> for i in 1:5
> if i == 1
> x = 42
> else
> @show x
> end
> end
> end
> 
> ```
> 
> is not sufficient and doesn’t work unfortunately.

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [November 20, 2020, 3:36pm UTC](https://discourse.julialang.org/t/scope-question-maybe-bug/50500/10 "2020-11-20T15:36:08Z")

</div>

Your second `foo` works fine.

---

<div class="post-metadata">

**Author:** ![FedericoStra](https://avatars.discourse-cdn.com/v4/letter/f/76d3ee/32.png) [@FedericoStra](https://discourse.julialang.org/u/FedericoStra)\
**Post date:** [November 20, 2020, 3:39pm UTC](https://discourse.julialang.org/t/scope-question-maybe-bug/50500/11 "2020-11-20T15:39:23Z")

</div>

Uhm… I don’t know what kind of hallucinations I must have had… 😕 I was probably working in a dirty workspace and used the wrong definition. You are perfectly right of course.
