# Not able to capture variable (via symbol) from outer scope?

**URL:** <https://discourse.julialang.org/t/not-able-to-capture-variable-via-symbol-from-outer-scope/46797>\
**Category:** New to Julia\
**Created:** [September 17, 2020, 6:45pm UTC](https://discourse.julialang.org/t/not-able-to-capture-variable-via-symbol-from-outer-scope/46797 "2020-09-17T18:45:57Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![conditionality](https://avatars.discourse-cdn.com/v4/letter/c/4af34b/32.png) [@conditionality](https://discourse.julialang.org/u/conditionality)\
**Post date:** [September 17, 2020, 6:45pm UTC](https://discourse.julialang.org/t/not-able-to-capture-variable-via-symbol-from-outer-scope/46797/1 "2020-09-17T18:45:58Z")

</div>

I have the following minimal example:

```julia
function foo()
    myvar1 = 55
    function bar()
        println(myvar1) #<- OK
        s = Symbol("myvar", 1)
        println(@eval $s) # <-ERROR: LoadError: UndefVarError: myvar1 not defined
    end
    bar()
end
foo()
myvar2 = 77
s = Symbol("myvar", 2)
println(@eval $s) #<-- OK

```

Why can’t I access myvar1 by evaluating the proper symbol?

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [September 17, 2020, 6:48pm UTC](https://discourse.julialang.org/t/not-able-to-capture-variable-via-symbol-from-outer-scope/46797/2 "2020-09-17T18:48:37Z")

</div>

What do you mean? the variable `myvar1` hasn’t been defined yet when you call the function. what you are doing is equivelent to typing

```julia
mynewvar2134

```

into the REPL. You will get an error that it is undefined.

---

<div class="post-metadata">

**Author:** ![conditionality](https://avatars.discourse-cdn.com/v4/letter/c/4af34b/32.png) [@conditionality](https://discourse.julialang.org/u/conditionality)\
**Post date:** [September 17, 2020, 6:50pm UTC](https://discourse.julialang.org/t/not-able-to-capture-variable-via-symbol-from-outer-scope/46797/3 "2020-09-17T18:50:22Z")

</div>

@ [pdeffebach](https://discourse.julialang.org/u/pdeffebach) But I did define myvar1 on row 2, before calling bar().

---

<div class="post-metadata">

**Author:** ![lucas711642](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lucas711642/32/12051_2.png) [@lucas711642](https://discourse.julialang.org/u/lucas711642)\
**Post date:** [September 17, 2020, 6:52pm UTC](https://discourse.julialang.org/t/not-able-to-capture-variable-via-symbol-from-outer-scope/46797/4 "2020-09-17T18:52:17Z")

</div>

`@eval` and `eval` execute in global scope. `myvar1` is defined in a local scope.

---

<div class="post-metadata">

**Author:** ![conditionality](https://avatars.discourse-cdn.com/v4/letter/c/4af34b/32.png) [@conditionality](https://discourse.julialang.org/u/conditionality)\
**Post date:** [September 17, 2020, 7:03pm UTC](https://discourse.julialang.org/t/not-able-to-capture-variable-via-symbol-from-outer-scope/46797/5 "2020-09-17T19:03:36Z")

</div>

I see. Is there anyway to accomplishing what I want: I want to be able to pass a digit (“1” in the case above) to the function bar, use that digit “X” to capture the variable myvarX in foo(), and use it to compute stuff within bar()?

(I realize I can just send in the variable itself, but I’m trying to understand the Julia language.)

---

<div class="post-metadata">

**Author:** ![lucas711642](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lucas711642/32/12051_2.png) [@lucas711642](https://discourse.julialang.org/u/lucas711642)\
**Post date:** [September 17, 2020, 7:24pm UTC](https://discourse.julialang.org/t/not-able-to-capture-variable-via-symbol-from-outer-scope/46797/6 "2020-09-17T19:24:22Z")

</div>

It is not possible using only functions. It seems that you are trying to work with [metaprogramming](https://docs.julialang.org/en/v1/manual/metaprogramming/). You can define a macro that receives an input and returns code:

```julia
macro append_myvar(x)
	esc(Symbol(:myvar, x))
end
function foo()
    myvar1 = 55
    function bar()
        println(myvar1) #<- OK
        s = @append_myvar 1
        println(s)
    end
    bar()
end

```

Note that you shouldn’t use metaprogramming for this. It is just an example. In your case, an `Array` or `Dict` storing `[myvar1, myvar2...]` is more appropriate.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [September 17, 2020, 7:25pm UTC](https://discourse.julialang.org/t/not-able-to-capture-variable-via-symbol-from-outer-scope/46797/7 "2020-09-17T19:25:22Z")

</div>

No you can’t. Do not try to construct variable names at runtime. It is also **NOT** possible with macros. @lucas711642’s post does not do anything different from writing `myvar1` directly.

---

<div class="post-metadata">

**Author:** ![lucas711642](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lucas711642/32/12051_2.png) [@lucas711642](https://discourse.julialang.org/u/lucas711642)\
**Post date:** [September 17, 2020, 7:27pm UTC](https://discourse.julialang.org/t/not-able-to-capture-variable-via-symbol-from-outer-scope/46797/8 "2020-09-17T19:27:55Z")

</div>

Yes, the code I provided only works with the `1` hard-coded in the function. You cannot pass the argument `x` to the macro at run time.

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [September 17, 2020, 7:29pm UTC](https://discourse.julialang.org/t/not-able-to-capture-variable-via-symbol-from-outer-scope/46797/9 "2020-09-17T19:29:21Z")

</div>

OP consider using a dictionary to store values instead of making variables with names generated at run time.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [September 17, 2020, 7:58pm UTC](https://discourse.julialang.org/t/not-able-to-capture-variable-via-symbol-from-outer-scope/46797/10 "2020-09-17T19:58:27Z")

</div>

> [@pdeffebach](#):
>
> OP consider using a dictionary to store values

Yes, this seems to fall into category 3 of [my list of common mis-applications of metaprogramming](https://discourse.julialang.org/t/how-to-warn-new-users-away-from-metaprogramming/35022/22). See also my [2019 JuliaCon talk on why you mostly shouldn’t use metaprogramming](https://youtu.be/mSgXWpvQEHE).

---

<div class="post-metadata">

**Author:** ![lucas711642](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lucas711642/32/12051_2.png) [@lucas711642](https://discourse.julialang.org/u/lucas711642)\
**Post date:** [September 18, 2020, 7:01am UTC](https://discourse.julialang.org/t/not-able-to-capture-variable-via-symbol-from-outer-scope/46797/11 "2020-09-18T07:01:04Z")

</div>

IMHO, using metaprogramming to create variables systematically can be quite handy in some cases. In my work, for example, I have a composite type (say `MyType`) that has a bunch of fields (say `field1`, `field2`, `field3`…). An instance of this type is passed to a function like the following:

```julia
function foo(myarg::MyType, ...)
	field1 = myarg.field1; field2 = myarg.field2 ...
	...
end

```

wait, these statements on the first line seem tedious. So I use a macro `@fields2variables` which in turn receives:

```julia
function foo(myarg::MyType, ...)
	@fields2variables MyType myarg
	...
end

```

and, as long as `MyType` is defined, `@fields2variables` gets its `fieldnames` and transform the code into:

```julia
function foo(myarg::MyType, ...)
	local field1, field2 ... = myarg.field1, myarg.field2, ...
	...
end

```

where the `local` keyword prevents us from incorrectly modifying variables in the enclosing scope.

Another common example in my code is something like:

```julia
@inbounds for k = eachindex(a, b, ...)
	ak = a[k]; bk = b[k]; ...
	...
end

```

whose first line can also be processed by a macro in a similar way.

I think macros like those are very convenient when writing internal code, but they probably shouldn’t be part of a public API, because they can hide some bugs (although the `local` keyword usually helps preventing bugs in the aforementioned examples), so you have to be careful when using them. Of course, the validity this kind of usage is just my opinion.

Again, this does not seem to be the case of the OP’s question, where an `Array` or `Dict` seems to be more appropriate.
