# Running Tests vs. Debugging gives different results

**URL:** <https://discourse.julialang.org/t/running-tests-vs-debugging-gives-different-results/52554>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [December 29, 2020, 5:11am UTC](https://discourse.julialang.org/t/running-tests-vs-debugging-gives-different-results/52554 "2020-12-29T05:11:25Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![jasonhnicholson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jasonhnicholson/32/20554_2.png) [@jasonhnicholson](https://discourse.julialang.org/u/jasonhnicholson)\
**Post date:** [December 29, 2020, 5:11am UTC](https://discourse.julialang.org/t/running-tests-vs-debugging-gives-different-results/52554/1 "2020-12-29T05:11:25Z")

</div>

When I normally run `tester.jl` below that calls my function `encode(),` it fails with a stack trace. When I debug run it in VS Code, it runs fine and does not fail. I even get the answer I expect. I am using VScode 1.52.1 with Julia 1.5.3.

**VScode info:**  
Version: 1.52.1 (user setup)  
Commit: ea3859d4ba2f3e577a159bc91e3074c5d85c0523  
Date: 2020-12-16T16:34:46.910Z  
Electron: 9.3.5  
Chrome: 83.0.4103.122  
Node.js: 12.14.1  
V8: 8.3.110.13-electron.0  
OS: Windows\_NT x64 10.0.18363

```julia
# run-length-encoding.jl
function encode(str)
    # Run-length encoding (RLE)
    rle = "";

    n = length(str);

    for i in 1:n
        if i==1 # setup on the first iteration
            c = str[1];
            runLength = 1;
        elseif c == str[i]
            runLength +=1;
        else
            # Record current run
            rle = runLength==1 ? string(rle, c) : string(rle, runLength, c);

            # restart run
            c = str[i];
            runLength = 1;
        end
        # Handle the end of the string
        if i==n
            rle = runLength==1 ? string(rle, c) : string(rle, runLength, c);
        end
    end

    return rle;
end

```

```julia
# tester.jl
include("run-length-encoding.jl");
encode("XYZ")

```

Stack Trace:

```julia
ERROR: LoadError: UndefVarError: c not defined
Stacktrace:
 [1] encode(::String) at c:\Users\jason\Exercism\julia\run-length-encoding\run-length-encoding.jl:11
 [2] top-level scope at c:\Users\jason\Exercism\julia\run-length-encoding\tester.jl:2
 [3] include_string(::Function, ::Module, ::String, ::String) at .\loading.jl:1088
 [4] include_string(::Module, ::String, ::String) at .\loading.jl:1096
 [5] invokelatest(::Any, ::Any, ::Vararg{Any,N} where N; kwargs::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}) at .\essentials.jl:710
 [6] invokelatest(::Any, ::Any, ::Vararg{Any,N} where N) at .\essentials.jl:709
 [7] inlineeval(::Module, ::String, ::Int64, ::Int64, ::String; softscope::Bool) at c:\Users\jason\.vscode\extensions\julialang.language-julia-1.0.10\scripts\packages\VSCodeServer\src\eval.jl:185    
 [8] (::VSCodeServer.var"#61#65"{String,Int64,Int64,String,Module,Bool,VSCodeServer.ReplRunCodeRequestParams})() at c:\Users\jason\.vscode\extensions\julialang.language-julia-1.0.10\scripts\packages\VSCodeServer\src\eval.jl:144
 [9] withpath(::VSCodeServer.var"#61#65"{String,Int64,Int64,String,Module,Bool,VSCodeServer.ReplRunCodeRequestParams}, ::String) at c:\Users\jason\.vscode\extensions\julialang.language-julia-1.0.10\scripts\packages\VSCodeServer\src\repl.jl:124
 [10] (::VSCodeServer.var"#60#64"{String,Int64,Int64,String,Module,Bool,Bool,VSCodeServer.ReplRunCodeRequestParams})() at c:\Users\jason\.vscode\extensions\julialang.language-julia-1.0.10\scripts\packages\VSCodeServer\src\eval.jl:142
 [11] hideprompt(::VSCodeServer.var"#60#64"{String,Int64,Int64,String,Module,Bool,Bool,VSCodeServer.ReplRunCodeRequestParams}) at c:\Users\jason\.vscode\extensions\julialang.language-julia-1.0.10\scripts\packages\VSCodeServer\src\repl.jl:36
 [12] (::VSCodeServer.var"#59#63"{String,Int64,Int64,String,Module,Bool,Bool,VSCodeServer.ReplRunCodeRequestParams})() at c:\Users\jason\.vscode\extensions\julialang.language-julia-1.0.10\scripts\packages\VSCodeServer\src\eval.jl:110
 [13] with_logstate(::Function, ::Any) at .\logging.jl:408
 [14] with_logger at .\logging.jl:514 [inlined]
 [15] (::VSCodeServer.var"#58#62"{VSCodeServer.ReplRunCodeRequestParams})() at c:\Users\jason\.vscode\extensions\julialang.language-julia-1.0.10\scripts\packages\VSCodeServer\src\eval.jl:109
 [16] #invokelatest#1 at .\essentials.jl:710 [inlined]
 [17] invokelatest(::Any) at .\essentials.jl:709
 [18] macro expansion at c:\Users\jason\.vscode\extensions\julialang.language-julia-1.0.10\scripts\packages\VSCodeServer\src\eval.jl:27 [inlined]
 [19] (::VSCodeServer.var"#56#57")() at .\task.jl:356
in expression starting at c:\Users\jason\Exercism\julia\run-length-encoding\tester.jl:2

```

My hunch is that c’s scope and definition are confined to the for-loop. In the debug run, c is defined just fine. In a normal run, c probably is optimized away, or somehow the for loop scope causes it not to be defined. Anyway, I think there is some bad practice here that I am violating but am a noob and still learning.

Thank you for explaining what is going on to a new Julia user.

---

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [December 29, 2020, 6:33am UTC](https://discourse.julialang.org/t/running-tests-vs-debugging-gives-different-results/52554/2 "2020-12-29T06:33:55Z")

</div>

When you are in a loop, think that all the variables created in the loop (and the iterator if it’s a `for` loop) are erased after each iteration. So, `c` does not exist in the second and later iterations when you call it in the `elseif`.

It could happen that when you were debugging you had defined another variable `c` in the global scope, and the loop is using it, maybe?

---

<div class="post-metadata">

**Author:** ![jasonhnicholson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jasonhnicholson/32/20554_2.png) [@jasonhnicholson](https://discourse.julialang.org/u/jasonhnicholson)\
**Post date:** [December 29, 2020, 6:20pm UTC](https://discourse.julialang.org/t/running-tests-vs-debugging-gives-different-results/52554/3 "2020-12-29T18:20:03Z")

</div>

Thanks for replying, @heliosdrm. 🙂

No, there is nothing in the global space. I have restarted VScode and also ran this in Juno. The results are similar. The code runs in debug mode and doesn’t run in normal mode.

```julia
# stack trace in Juno using a Julia REPL in a normal run
julia> include("tester.jl")
ERROR: LoadError: UndefVarError: c not defined
Stacktrace:
 [1] encode(::String) at C:\Users\jason\Exercism\julia\run-length-encoding\run-length-encoding.jl:9
 [2] top-level scope at C:\Users\jason\Exercism\julia\run-length-encoding\tester.jl:2
 [3] include(::String) at .\client.jl:457
 [4] top-level scope at none:1
in expression starting at C:\Users\jason\Exercism\julia\run-length-encoding\tester.jl:2

```

I think I need to understand the scope of variables inside of a for a loop.

---

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [December 29, 2020, 7:15pm UTC](https://discourse.julialang.org/t/running-tests-vs-debugging-gives-different-results/52554/4 "2020-12-29T19:15:17Z")

</div>

> [@jasonhnicholson](#):
>
> I think I need to understand the scope of variables inside of a for a loop.

Normally it’s as I told before: variables assigned inside a loop (such as `c = ...`) are local _for each iteration_ (and the iterator of `for` loops is local as well), unless explicitly declared global (or in the REPL since 1.5, if there is a global with the same name). But you are right, in debug mode that rule does not hold. Not only in VS Code, also with [Debugger.jl](https://github.com/JuliaDebug/Debugger.jl):

(after adding a breakpoint in line 9:)

```julia
julia> @run encode("XYZ")
Hit breakpoint:
In encode(str) at /home/meliana/prueba/run-length-encoding.jl:2
  5  
  6 n = length(str);
  7  
  8 for i in 1:n
> 9 if i==1 # setup on the first iteration
 10 c = str[1];
 11 runLength = 1;
 12 elseif c == str[i]
 13 runLength +=1;

About to run: (==)(1, 1)
1|debug> fr
[1] encode(str) at /home/meliana/prueba/run-length-encoding.jl:2
  | str::String = "XYZ"
  | rle::String = ""
  | n::Int64 = 3
  | ::Tuple{Int64,Int64} = (1, 1)
  | i::Int64 = 1
1|debug> c
Hit breakpoint:
In encode(str) at /home/meliana/prueba/run-length-encoding.jl:2
  5  
  6 n = length(str);
  7  
  8 for i in 1:n
> 9 if i==1 # setup on the first iteration
 10 c = str[1];
 11 runLength = 1;
 12 elseif c == str[i]
 13 runLength +=1;

About to run: (==)(2, 1)
1|debug> fr
[1] encode(str) at /home/meliana/prueba/run-length-encoding.jl:2
  | str::String = "XYZ"
  | rle::String = ""
  | n::Int64 = 3
  | ::Tuple{Int64,Int64} = (2, 2)
  | i::Int64 = 2
  | c::Char = 'X'
  | runLength::Int64 = 1

```

`c` exists at the outset of the second iteration, with the value that was assigned in the first one. Bug or feature?

---

<div class="post-metadata">

**Author:** ![jasonhnicholson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jasonhnicholson/32/20554_2.png) [@jasonhnicholson](https://discourse.julialang.org/u/jasonhnicholson)\
**Post date:** [December 29, 2020, 7:18pm UTC](https://discourse.julialang.org/t/running-tests-vs-debugging-gives-different-results/52554/5 "2020-12-29T19:18:25Z")

</div>

Thank you for the explanation!

I am not sure if it is a bug or a feature. For now, it is best for me to understand how it works and then fix it. I feel like too much of a noob to declare this a bug.

---

<div class="post-metadata">

**Author:** ![jasonhnicholson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jasonhnicholson/32/20554_2.png) [@jasonhnicholson](https://discourse.julialang.org/u/jasonhnicholson)\
**Post date:** [December 29, 2020, 7:45pm UTC](https://discourse.julialang.org/t/running-tests-vs-debugging-gives-different-results/52554/6 "2020-12-29T19:45:50Z")

</div>

@heliosdrm, thank you for your help. The main issue is` c` and `runLength` were not visible from iteration to iteration in a normal run but were visible in a debug run. Defining `c` and `runLength` before the loop fixes the problem.

```julia
function encode(str)
    # Run-length encoding (RLE)
    rle = "";

    n = length(str);

    # Variables that are defined, so they persist from iteration to iteration. 
    c = "";
    runLength = NaN;
    for i in 1:n
        if i==1 # setup on the first iteration
            c = str[1];
            runLength = 1;
        elseif c == str[i]
            runLength +=1;
        else
            # Record current run
            rle = runLength==1 ? string(rle, c) : string(rle, runLength, c);

            # restart run
            c = str[i];
            runLength = 1;
        end
        # Handle the end of the string
        if i==n
            rle = runLength==1 ? string(rle, c) : string(rle, runLength, c);
        end
    end

    return rle;
end

```

The relevant documentation is [Scope of Variables](https://docs.julialang.org/en/v1/manual/variables-and-scoping/#scope-of-variables). To summarize, the two different behaviors are a feature, and it must be understood why by reading the linked page. It is a mandatory read for any knew Julia user. This whole thread was my lesson in the scope of variables.

A short example demonstrating the lesson learned is below. c is not defined after the first iteration in running f() below. c is part of the local scope of the for-loop.

```julia
julia> function f()
           for i = 1:4
               if i==1
                   c = 1;
               end
               println("i=$i, Is c defined? Answer: $(@isdefined(c))")
           end
       end
f (generic function with 1 method)

julia> f()
i=1, Is c defined? Answer: true
i=2, Is c defined? Answer: false
i=3, Is c defined? Answer: false
i=4, Is c defined? Answer: false

```

The fix is to define the variable before the for-loop so it is part of the global scope. Running f2() below shows the result.

```julia
julia> function f2()
           c = 0;
           for i = 1:4
               if i==1
                   c = 1;
               end
               answer = @isdefined(c)
               print("i=$i, Is c defined? Answer: $answer.")
               if answer
                   print(" c=$c.\n");
               end
           end
       end
f2 (generic function with 1 method)

julia> f2()
i=1, Is c defined? Answer: true. c=1.
i=2, Is c defined? Answer: true. c=1.
i=3, Is c defined? Answer: true. c=1.
i=4, Is c defined? Answer: true. c=1.

```

---

<div class="post-metadata">

**Author:** ![heliosdrm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/heliosdrm/32/3851_2.png) [@heliosdrm](https://discourse.julialang.org/u/heliosdrm)\
**Post date:** [December 30, 2020, 12:11am UTC](https://discourse.julialang.org/t/running-tests-vs-debugging-gives-different-results/52554/7 "2020-12-30T00:11:54Z")

</div>

I’m not that sure of this being really a feature in the case of the debugger. So I filed this issue:

[https://github.com/JuliaDebug/Debugger.jl/issues/282](https://github.com/JuliaDebug/Debugger.jl/issues/282)

---

<div class="post-metadata">

**Author:** ![jasonhnicholson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jasonhnicholson/32/20554_2.png) [@jasonhnicholson](https://discourse.julialang.org/u/jasonhnicholson)\
**Post date:** [December 30, 2020, 12:46am UTC](https://discourse.julialang.org/t/running-tests-vs-debugging-gives-different-results/52554/8 "2020-12-30T00:46:02Z")

</div>

@heliosdrm, thanks for filing an issue on Github. I don’t have the confidence yet to say it is a bug.
