@nbinclude in the REPL

Maybe this is a bug report. Please advise.

I have a small notebook that runs perfectly when I open it in Jupyter, but not at the REPL.

Working at a freshly-started Julia 1.2.0 REPL, when I say

using NBInclude
@nbinclude("CALO-MWE.ipynb")

I expect the minimalist workbook attached here to run successfully and print the computed result, but instead I get the error message below:

ERROR: LoadError: UndefVarError: slacksum not defined
Stacktrace:
 [1] top-level scope at /home/loew/loewCloud/CALO/2019-10/CALO-MWE.ipynb:In[2]:4
 [2] include_string(::Module, ::String, ::String) at ./loading.jl:1064
 [3] my_include_string(::Module, ::String, ::String, ::Nothing, ::Bool) at /home/loew/.julia/packages/NBInclude/m4rfj/src/NBInclude.jl:29
 [4] #nbinclude#1(::Bool, ::UnitRange{Int64}, ::Regex, ::typeof(identity), ::Bool, ::typeof(nbinclude), ::Module, ::String) at /home/loew/.julia/packages/NBInclude/m4rfj/src/NBInclude.jl:82
 [5] nbinclude(::Module, ::String) at /home/loew/.julia/packages/NBInclude/m4rfj/src/NBInclude.jl:53
 [6] top-level scope at REPL[14]:1
in expression starting at /home/loew/loewCloud/CALO/2019-10/CALO-MWE.ipynb:In[2]:3 

I have Julia 1.2.0, with IJulia v1.20.0 and NBInclude v2.1.0.

What do you suggest?

Sorry, new here, don’t know how to attach the file named CALO-MWE.ipynb, so I’ll just paste it here:

{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "slacks = [1,2];"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Total slack: 3.\n"
     ]
    }
   ],
   "source": [
    "slacksum = 0;\n",
    "\n",
    "for sl in slacks\n",
    "        slacksum += sl\n",
    "end\n",
    "println(\"\\nTotal slack: $(slacksum).\")"
   ]
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Julia 1.2.0",
   "language": "julia",
   "name": "julia-1.2"
  },
  "language_info": {
   "file_extension": ".jl",
   "mimetype": "application/julia",
   "name": "julia",
   "version": "1.2.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}

I think you might be running into a scope issue, although I’m not 100% sure how scoping works in notebooks run from the REPL.

My best guess: your code includes the loop

slacksum = 0
for sl in slacks
    slacksum += sl
end

This works in the notebook because Notebooks by default use SoftGlobalScope.jl, however if you run the same code in the REPL, which doesn’t use SoftGlobalScope it raises an error because the loop creates its own scope, in which the variable slacksum is not defined. The solution is to annotate the line in the loop with global, to indicate that the loop is accessing a variable that’s defined in global scope.

The general solution to these things is not to run code in global scope, but to enclose everything in a function, although I see how this can be tricky in Notebooks with cell by cell execution.

There is a bit more info on the SoftGlobalScope here:
https://github.com/stevengj/NBInclude.jl/issues/11
and here:
https://github.com/stevengj/SoftGlobalScope.jl

Yes. IJulia has a patch for the scoping issue. To apply for your example, go @nbinclude(foo.ipynb, softscope=true)

1 Like

Thanks for the informative responses. The suggestion from @jlperla works for me, after changing the comma to a semicolon (and installing the SoftGlobalScope package):

@nbinclude(foo.ipynb; softscope=true)
1 Like