Valeria
Valeria

Reputation: 1232

Julia: read file into string out of local scope

It is the first time I am writing in Julia and I am confused by how the variables scoping works, even though I have read it in the docs.

I am writing this simple script to read the contents of the JSON file and parse it into Dict:

import JSON
using ArgParse

s = ArgParseSettings()
@add_arg_table! s begin
    "filename"
        help = "a positional argument"
        arg_type = String
        required = true
end

function main(args)
    jsontxt = ""
    open(args["filename"], "r") do f
        global jsontxt = read(f, String)  # file information to string
        println(jsontxt)
    end
    model_params = JSON.parse(jsontxt)  # parse and transform data
    println(model_params)
end

parsed_args = parse_args(ARGS, s)
main(parsed_args)

So, I expect jsontxt variable to contain the result of read(f, String) when I pass it to JSON.parse. However, it seems that when I call JSON.parse, the jsontxt is empty as in the main function scope. My expectation from reading analogous (or so I have thought) example on reading files was that I would change jsontxt contents if I define it as global variable, which does not seem to happen.

What have I misunderstood and how to correct it?

Example JSON for running the script:

{
    "glossary": {
        "title": "example glossary",
        "GlossDiv": {
            "title": "S",
            "GlossList": {
                "GlossEntry": {
                    "ID": "SGML",
                    "SortAs": "SGML",
                    "GlossTerm": "Standard Generalized Markup Language",
                    "Acronym": "SGML",
                    "Abbrev": "ISO 8879:1986",
                    "GlossDef": {
                        "para": "A meta-markup language, used to create markup languages such as DocBook.",
                        "GlossSeeAlso": ["GML", "XML"]
                    },
                    "GlossSee": "markup"
                }
            }
        }
    }
}

Upvotes: 1

Views: 462

Answers (1)

pfitzseb
pfitzseb

Reputation: 2554

Your code works fine if you simply get rid of the global annotation. jsontxt is defined in a local scope, so global jsontxt will not refer to it.

Give the following code a go to understand what's going on

import JSON
using ArgParse

s = ArgParseSettings()
@add_arg_table! s begin
    "filename"
        help = "a positional argument"
        arg_type = String
        required = true
end

jsontxt = ""

function main(args)
    jsontxt = "{}" # add a `global` here and your code works fine
    open(args["filename"], "r") do f
        global jsontxt = read(f, String)  # remove the `global` here and your code works fine
        println("inner local scope:")
        println(jsontxt)
    end
    model_params = JSON.parse(jsontxt)  # parse and transform data
    println("outer local scope:")
    println(model_params)
end

parsed_args = parse_args(ARGS, s)
main(parsed_args)
println("global scope:")
println(jsontxt)

It will output something like

$ julia test.jl test.json
inner local scope:
{
    "foo": "bar"
}
outer local scope:
Dict{String,Any}()
global scope:
{
    "foo": "bar"
}

Upvotes: 1

Related Questions