Executing code blocks with REPL workspace

Hi,

I have a very basic question about Julia: I’ve written a function in julia and im trying to debug the code. I can mark a block of code and execute it using Shift+Enter.

However, when executing the code like this, the workspace seems not to be known for Julia.

Example:
My function is load_data(filepath). I wanna just run this line of code. I defined the filepath in the REPL to make it work, but it just throws an UndefVarError.

What basic concept am I not getting here?

Best

I’m not sure if I fully understand your situation. Are you using VS Code and sending code to the REPL?

The REPL does not know what is in your file. If you did not send a line such as the following then the variable will not be defined.

filepath = "my_secret_file.txt"

There is also global and local scope to consider.

If you type filepath in the REPL, is it defined?

Could you show us the block of code thay produces the error?

Hi,
thanks for your reply. It’s as follows:
If I mark the following lines of code in my code.jl file and execute it, everything works fine:

filepath = "my_secret_file.txt"
load_data(filepath)

However, when I define filepath using the REPL (filepath = "my_secret_file.txt") and then just mark the second line and execute only this from the file

load_data(filepath)

I obtain the error, that the variable filepath is not defined (UndefVarError)

Best

Welcome to the Julia discourse.

From afar still a bit hard to tell without more details. If the script itself running (from which folder?) would find the file, then the Julia REPL might be started in a different folder? You could cd into the right folder as one command in REPL then after the start?
With ; you also have a shell mode in Julia REPL (a red shell> upfront) where you can easier check with cd and ls and such where you are and where to go.

Please confirm. Are you are using VS Code or another IDE or editor?

1 Like

Hi, thanks for your reply. Yes, I’m using the latest release of VS Code.

I just played around a litttle bit and observed the following:
The problem above does not appear (aka everything works) when I’m using a fresh Julia session.
Since the function load_data() is part of my package, I then import the package with using MyPackage in the REPL, which makes the function load_data() available. But than, everytime I execute the code snippet, it does not know variables defined through the REPL.

I’m having to extrapolate here since you are not providing any example code. What I understand is that you have a package as follows.

module MyPackage

export load_data

function load_data(filename)
    println("Loading ", filename)
end

end

You use it as follows in the REPL.

julia> using MyPackage

julia> filename = "my_secret_file.txt"
"my_secret_file.txt"

julia> load_data(filename)
Loading my_secret_file.txt

julia> filename2 = "my_secret_file2.txt"
"my_secret_file2.txt"

julia> load_data(filename2)
Loading my_secret_file2.txt

julia> filename3 = "my_other_file.txt"

In a file, in VS Code you have the following.

load_data(filename3)

You push Ctrl-enter in vscode, and you get

julia> load_data(filename3)
ERROR: UndefVarError: `filename3` not defined
Stacktrace:
 [1] top-level scope
   @ REPL[30]:1

Is that right? How did you start the REPL?

2 Likes

To check, I want to make sure that you are starting the Julia REPL via the VS Code Julia Extension by either pressing “Alt-J, Alt-O” or doing “Ctrl-Shift-P” and selecting “Julia: Start REPL”. That should start up a REPL and be the REPL that VS Code will sends the code to execute on.

What I’m worried about is that you are starting the Julia REPL by creating a new terminal, and then running the Julia REPL via the command line as follows. If you do this, then you have two Julia sessions that do not know about each other.

This happens all the time for me, and it is very annoying. Same issue as here:

You need to change the REPL module to match your package module. Otherwise, the REPL and package namespaces are kept separate. I still do not understand why this isn’t done automatically.

1 Like

Thx @mkitti for your very detailed explanation the different terminals.

Thank you @Nathan_Boyer Nathan, that’s the issue I had!

Now it works almost… If I import my package I have to switch the modules from the REPL and from VSCode to the same package. But the VS code workspace explorer only shows the workspace of the base-module (so I can’t see any variables defined in the module-workspace itself). How can I change that?

Are you using Revise.jl?

That makes most of this unnecessary during package development.

VSCode automatically uses Revise.jl.

I wish it was unnecessary.

I think most people get around this limitation by working in the Main REPL module and only typing/executing full function calls defined in their package (Method 1 in this link), but that method doesn’t work very well if you need to test individual lines of your package code (rather than entire functions). Changing your REPL module is the only way I have found to do that.

I’m happy to be proven wrong and shown something simpler, but I’ve been asking about this for a long time, and no one has given me a good answer:

If it’s a few lines of code, then I just use do import MyPackage: A, B, C.

There is also an export all macro call that can be used.

# export all
for n in names(@__MODULE__; all=true)
    if Base.isidentifier(n) && n ∉ (Symbol(@__MODULE__), :eval, :include)
        @eval export $n
    end
end

Usually though I might start a function within the package of interest and with just the lines of interest I want to test, and then run that from the REPL.

There are also packages such as GitHub - JuliaDebug/Infiltrator.jl: No-overhead breakpoints in Julia that you let step into a local environment of a function.

Some combination of the following is helpful to me

  1. An exportall(mod::Module)` function
function exportall(mod)
    for n in names(mod, all = true)
        if Base.isidentifier(n) && n ∉ (Symbol(mod), :eval)
            @eval mod export $n
        end
    end
end

I have this in my startup.jl

  1. A main() function inside the module which looks like
function main()
@eval Main begin
    ...
end
end

The only problem is that you need to make sure you run exportall before main()

This has a nice combination of

  1. Revise.jl works
  2. You can play around with functions inside your module
  3. The temporary variables you make at the REPL aren’t visible inside your module, so you don’t accidentally define global things that get used in your module.
1 Like