# Converting String to Datatype with Meta.parse

**URL:** https://discourse.julialang.org/t/converting-string-to-datatype-with-meta-parse/33024
**Category:** General Usage
**Created:** [January 6, 2020, 12:01pm UTC](https://discourse.julialang.org/t/converting-string-to-datatype-with-meta-parse/33024 "2020-01-06T12:01:32Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![YongHee-Kim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yonghee-kim/32/5965_2.png) [@YongHee-Kim](https://discourse.julialang.org/u/YongHee-Kim)
#### Post date: [January 6, 2020, 12:01pm UTC](https://discourse.julialang.org/t/converting-string-to-datatype-with-meta-parse/33024/1 "2020-01-06T12:01:32Z")

</div>

I’ve made a package to create [JSONPointer](https://tools.ietf.org/html/rfc6901) from a string, then construct the Dictionary from JSONPointer data.

But I’ve added extra functionality to define static type for JSONPointer.  
here is example

```julia
pkg>add XLSXasJSON

using XLSXasJSON
import XLSXasJSON.JSONPointer

p = JSONPointer("/a::Int")
d = Dict(p)
d[p] = "a" # throws assert 

```

Which throws assert as I intended but this doesn’t work

```julia
struct Foo 
end
p = JSONPointer("/a::Foo")
d = Dict(p) # throws UndefVarError

```

[https://github.com/devsisters/XLSXasJSON.jl/blob/master/src/pointer.jl#L26](https://github.com/devsisters/XLSXasJSON.jl/blob/master/src/pointer.jl#L26)

Is there a way I can make this work for user-defined type?

---

<div class="post-metadata">

### Author: ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)
#### Post date: [January 6, 2020, 1:41pm UTC](https://discourse.julialang.org/t/converting-string-to-datatype-with-meta-parse/33024/2 "2020-01-06T13:41:03Z")

</div>

Your problem lies probably in the use of `eval` rather than `Meta.parse` (which, incidentally, you could probably replace by `Symbol` in this case). The problem is that `eval` evaluates an expression within the context of a module. If everything was defined in the same module, you wouldn’t have any problem:

```julia
julia> struct Foo end

julia> gettype(s::String) = Meta.parse(s) |> eval
gettype (generic function with 1 method)

julia> gettype("Int")
Int64

julia> gettype("Foo")
Foo

```

In your case however, since your `JSONPointer` constructor is in a separate package (and therefore a separate module), the type symbol is `eval`led in the context of the `JSONPointer` module, where type `Foo` does not exist. Hence the error:

```julia
julia> module MyModule
       gettype(s::String) = Meta.parse(s) |> eval
       end
Main.MyModule

# Still works because `Int` is defined both in Main and MyModule
# (and refers to the same thing, which could not be the case!)
julia> MyModule.gettype("Int")
Int64

# Does not work because Foo is unknown in the context of MyModule
julia> MyModule.gettype("Foo")
ERROR: UndefVarError: Foo not defined

```

One way you could circumvent the problem would be to add an argument providing the module in which type names have to be evaluated:

```julia
julia> module MyModule2
       gettype(s::String, mod=@ __MODULE__ ) = Symbol(s) |> mod.eval
       end
Main.MyModule2

# No absolute need to provide a module here
# (but it would probably be better anyway)
julia> MyModule2.gettype("Int")
Int64

# Same as above
julia> MyModule2.gettype("Foo")
ERROR: UndefVarError: Foo not defined

# Foo is known in the context of the calling module
julia> MyModule2.gettype("Foo", @ __MODULE__ )
Foo

```

  

* * *

For this type of reasons, using `eval` is sometimes considered “bad style”. I personally don’t know any way avoiding it in this case; hopefully someone more knowledgeable will chime in and propose a better solution…

---

<div class="post-metadata">

### Author: ![YongHee-Kim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yonghee-kim/32/5965_2.png) [@YongHee-Kim](https://discourse.julialang.org/u/YongHee-Kim)
#### Post date: [January 6, 2020, 2:20pm UTC](https://discourse.julialang.org/t/converting-string-to-datatype-with-meta-parse/33024/3 "2020-01-06T14:20:05Z")

</div>

Thank you for clarifying this 😀  
I will have to come up with an interface to provide the module name to XLSXasJSON.

---

<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: [January 6, 2020, 4:24pm UTC](https://discourse.julialang.org/t/converting-string-to-datatype-with-meta-parse/33024/4 "2020-01-06T16:24:58Z")

</div>

Providing a module is most likely not the correct solution.

The fundamental issue is that the a name is not enough to uniquely qualify an object (including types). A name needs to be combined with a name space to look up into.

Unless you have some specific use case that will always require the user to import all the needed types into the same namespace (which is basically not needed for anything else in the language) and unless the string is not meant to transfer generic information, you should not pass in the module separately.

If the string is used basically as code to pass local information, then you should not use string. You should pass in the information directly. If you are only using it to construct an object more easily, you can use a macro.

Otherwise you should encode the fully qualified name in the string.

---

<div class="post-metadata">

### Author: ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)
#### Post date: [January 6, 2020, 8:07pm UTC](https://discourse.julialang.org/t/converting-string-to-datatype-with-meta-parse/33024/5 "2020-01-06T20:07:29Z")

</div>

> [@yuyichao](#):
>
> A name needs to be combined with a name space to look up into.

Could you please elaborate on what a “name + namespace” combination is, if it is not a (name, module) pair?

---

<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: [January 6, 2020, 9:24pm UTC](https://discourse.julialang.org/t/converting-string-to-datatype-with-meta-parse/33024/6 "2020-01-06T21:24:25Z")

</div>

It’s a name module pair.

If you are asking what’s the difference between what I said and what you are suggesting, I’m saying that what’s missing is not a module for the function, it’s missing from the string.

Also something that I forgot to say, this is the simplest case to avoid eval, you are just accessing module member and you should just do that instead of eval. What you need is getfield or getproperty.

---

<div class="post-metadata">

### Author: ![ffevotte](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ffevotte/32/6587_2.png) [@ffevotte](https://discourse.julialang.org/u/ffevotte)
#### Post date: [January 6, 2020, 10:01pm UTC](https://discourse.julialang.org/t/converting-string-to-datatype-with-meta-parse/33024/7 "2020-01-06T22:01:47Z")

</div>

> [@yuyichao](#):
>
> If you are asking what’s the difference between what I said and what you are suggesting, I’m saying that what’s missing is not a module for the function, it’s missing from the string.

Thanks, it’s clearer that way.

  

> [@yuyichao](#):
>
> Also something that I forgot to say, this is the simplest case to avoid eval, you are just accessing module member and you should just do that instead of eval. What you need is getfield or getproperty.

Of course, that makes sense:

```julia
julia> struct Foo end
julia> getfield(@ __MODULE__ , Symbol("Foo"))
Foo

```

---

<div class="post-metadata">

### Author: ![YongHee-Kim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yonghee-kim/32/5965_2.png) [@YongHee-Kim](https://discourse.julialang.org/u/YongHee-Kim)
#### Post date: [January 7, 2020, 8:39am UTC](https://discourse.julialang.org/t/converting-string-to-datatype-with-meta-parse/33024/8 "2020-01-07T08:39:34Z")

</div>

hmm… But getfield doesn’t work for parametric type

```julia
julia> getfield(Main, Symbol("Union{Int, Missing}"))
julia> getfield(Main, Symbol("Array{Int, 1}"))

```

---

<div class="post-metadata">

### Author: ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)
#### Post date: [January 7, 2020, 1:30pm UTC](https://discourse.julialang.org/t/converting-string-to-datatype-with-meta-parse/33024/9 "2020-01-07T13:30:48Z")

</div>

I am not on computer but I think what you want for parametric is:

```julia
uatype = getfield(Main, :Array
typeparam = getfield(Main, :Int}
uatype{typeparam, 1}

```

You could use `Meta.parse` and then a little bit of logic to do this.

Its a question as to what module you should be using.  
To be preperly explict about the type in this case you should be using its originating module-- `Base`.  
But if you want what ever is in scope then `@ __MODULE__ `  
or if in repl and saving chacacters `Main`
