# How to read a string from a file with interpolation

**URL:** <https://discourse.julialang.org/t/how-to-read-a-string-from-a-file-with-interpolation/47913>\
**Category:** New to Julia\
**Tags:** strings, input-output, string-interpolation\
**Created:** [October 7, 2020, 5:30am UTC](https://discourse.julialang.org/t/how-to-read-a-string-from-a-file-with-interpolation/47913 "2020-10-07T05:30:38Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![mkarikom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkarikom/32/7096_2.png) [@mkarikom](https://discourse.julialang.org/u/mkarikom)\
**Post date:** [October 7, 2020, 5:30am UTC](https://discourse.julialang.org/t/how-to-read-a-string-from-a-file-with-interpolation/47913/1 "2020-10-07T05:30:39Z")

</div>

The file “test.txt” contains a single line:

```julia
I am $me

```

The following is intended to simply read the string and store the interpolated result in `str`:

```julia
me = "Sam"
str = read("test.txt", String);
str == "I am Sam"
false

```

---

<div class="post-metadata">

**Author:** ![timquelch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/timquelch/32/18278_2.png) [@timquelch](https://discourse.julialang.org/u/timquelch)\
**Post date:** [October 7, 2020, 8:14am UTC](https://discourse.julialang.org/t/how-to-read-a-string-from-a-file-with-interpolation/47913/2 "2020-10-07T08:14:12Z")

</div>

I do not know, but I have some premptive follow up questions for whoever does know.

At what point is string interpolation processed? Is it on string creation, string literal parsing, or at some other point?

My intuition would be when the actual string literal is parsed. Is there a way to force string interpolation on a string created from a non-literal?

---

<div class="post-metadata">

**Author:** ![MarcMush](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marcmush/32/18006_2.png) [@MarcMush](https://discourse.julialang.org/u/MarcMush)\
**Post date:** [October 7, 2020, 8:52am UTC](https://discourse.julialang.org/t/how-to-read-a-string-from-a-file-with-interpolation/47913/3 "2020-10-07T08:52:58Z")

</div>

parsing any arbitrary code is probably not a good idea

what about using a `Dict` and `replace`:

```julia
vars = Dict("me" => "Sam", "you" => "Max")
str = "I am \$me"
for (var, val) in vars
    str = replace(str, "\$"*var => val)
end

```

although this would cause problems if a variable name contains another variable name (eg if you have `$me` and `$metoo`)

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [October 7, 2020, 9:17am UTC](https://discourse.julialang.org/t/how-to-read-a-string-from-a-file-with-interpolation/47913/4 "2020-10-07T09:17:53Z")

</div>

If all your variables are in global scope, and you don’t care that much about performance, you can actually implement interpolation yourself relatively easily and then use `eval`:

```julia
if isdefined(Meta, :parseatom)
    const parseatom = Meta.parseatom
else
    parseatom(s, i; filename=nothing) = Meta.parse(s, i; greedy=false)
end

function parse_interpolation(s, filename)
    i = firstindex(s)
    buf = IOBuffer(maxsize=ncodeunits(s))
    ex = Expr(:string)
    while i <= ncodeunits(s)
        c = @inbounds s[i]
        i = nextind(s, i)
        if c === '$'
            position(buf) > 0 && push!(ex.args, String(take!(buf)))
            atom, i = parseatom(s, i; filename)
            Meta.isexpr(atom, :incomplete) && error(atom.args[1])
            atom !== nothing && push!(ex.args, atom)
        else
            print(buf, c)
        end
    end
    position(buf) > 0 && push!(ex.args, String(take!(buf)))
    return ex
end

```

```julia
julia> open("test.txt", "w") do io
           print(io, raw"I am $me")
       end

julia> me = "Sam"
"Sam"

julia> str = eval(parse_interpolation(read("test.txt", String), "test.txt"))
"I am Sam"

```

Of course, you are executing arbitrary code from a text file, so you definitely want to be careful with this.

---

<div class="post-metadata">

**Author:** ![simeonschaub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/simeonschaub/32/216566_2.png) [@simeonschaub](https://discourse.julialang.org/u/simeonschaub)\
**Post date:** [October 7, 2020, 9:29am UTC](https://discourse.julialang.org/t/how-to-read-a-string-from-a-file-with-interpolation/47913/5 "2020-10-07T09:29:10Z")

</div>

Your intuition is right, regular string interpolation is processed inside Julia’s parser, so `"a $b c"` parses as `Expr(:string, "a ", :b, " c")`. This then gets transformed to `Base.string("a ", b, " c")` in lowering.  
If you want to do string interpolation programmatically, you need to implement the parsing yourself, like in my answer above, but that only gives you the expression tree, not the final string. Usually, this is implemented inside macros, so a macro could simply return this expression tree (escaped with `esc`), and interpolation would happen inside the macro caller’s scope. You can of course also use `eval`, like I did above, but that will only work in global scope and will be quite slow, because everything is executed at runtime.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [October 7, 2020, 10:57am UTC](https://discourse.julialang.org/t/how-to-read-a-string-from-a-file-with-interpolation/47913/6 "2020-10-07T10:57:33Z")

</div>

Unless you need the full power of `$` (for all valid Julia expressions), you may be interested in

[https://github.com/jverzani/Mustache.jl](https://github.com/jverzani/Mustache.jl)

---

<div class="post-metadata">

**Author:** ![mkarikom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkarikom/32/7096_2.png) [@mkarikom](https://discourse.julialang.org/u/mkarikom)\
**Post date:** [October 7, 2020, 5:28pm UTC](https://discourse.julialang.org/t/how-to-read-a-string-from-a-file-with-interpolation/47913/7 "2020-10-07T17:28:39Z")

</div>

It’s unfortunate that only one solution can be marked within Discourse

---

<div class="post-metadata">

**Author:** ![mkarikom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkarikom/32/7096_2.png) [@mkarikom](https://discourse.julialang.org/u/mkarikom)\
**Post date:** [October 7, 2020, 8:22pm UTC](https://discourse.julialang.org/t/how-to-read-a-string-from-a-file-with-interpolation/47913/8 "2020-10-07T20:22:02Z")

</div>

> [@Tamas\_Papp](#):
>
> Unless you need the full power of `$` (for all valid Julia expressions), you may be interested in

Thanks, this worked perfectly!
