# How to detect if an object is a user-defined struct

**URL:** <https://discourse.julialang.org/t/how-to-detect-if-an-object-is-a-user-defined-struct/19165>\
**Category:** General Usage\
**Created:** [January 1, 2019, 1:21pm UTC](https://discourse.julialang.org/t/how-to-detect-if-an-object-is-a-user-defined-struct/19165 "2019-01-01T13:21:47Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ferran\_Mazzanti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ferran_mazzanti/32/7458_2.png) [@Ferran\_Mazzanti](https://discourse.julialang.org/u/Ferran_Mazzanti)\
**Post date:** [January 1, 2019, 1:21pm UTC](https://discourse.julialang.org/t/how-to-detect-if-an-object-is-a-user-defined-struct/19165/1 "2019-01-01T13:21:48Z")

</div>

Hi,  
I’m building a function that receives an object as input, and depending on whether the type of this object is standard or user-defined (=composite type defined by the user through a struct) it must do one thing or another. Something like

```julia
function kroky(x)
   if typeof(x) == user_defined
      println("user-defined variable")
   else
      println("system-defined variable")
   end
end

```

such that if I define

```julia
mutable struct conch
  x :: Int
  y :: Float64
  conch() = new()
end

```

then with

```julia
zz = conch()
zz.x = 1
zz.y = 3.1416

```

one has

```julia
kroky(zz)
> user-defined variable
kroky(3.0)
> system-defined variable

```

Of course the action example is quite basic in this case, but I hope you get the idea of what I am after.

Thx for your help and happy new year 🙂

Ferran

---

<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:** [January 1, 2019, 1:44pm UTC](https://discourse.julialang.org/t/how-to-detect-if-an-object-is-a-user-defined-struct/19165/2 "2019-01-01T13:44:41Z")

</div>

This will be difficult since Julia is designed so that user-defined constructs are first class citizens. So in principle you have no reason to care.

That said, if you need this for eg introspection or debugging, you can use `parentmodule(T)` and check if it is `Base` (but you may need to walk up the chain of modules) or a standard library.

---

<div class="post-metadata">

**Author:** ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)\
**Post date:** [January 1, 2019, 1:53pm UTC](https://discourse.julialang.org/t/how-to-detect-if-an-object-is-a-user-defined-struct/19165/3 "2019-01-01T13:53:22Z")

</div>

May I ask what the use case is for this? It sounds a bit like [code smell](https://en.wikipedia.org/wiki/Code_smell); perhaps there are other ways to achieve what you’re trying to do?

---

<div class="post-metadata">

**Author:** ![dawbarton](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dawbarton/32/215461_2.png) [@dawbarton](https://discourse.julialang.org/u/dawbarton)\
**Post date:** [January 1, 2019, 1:58pm UTC](https://discourse.julialang.org/t/how-to-detect-if-an-object-is-a-user-defined-struct/19165/4 "2019-01-01T13:58:06Z")

</div>

As Tamas says, the concept of a user-defined type doesn’t really exist in Julia. However, there do exist primitive types (e.g., integers, floats, other chunks of raw memory), though primitive types might well not include all the types you are interested in. (And users are free to define their own new primitive types!)

```julia
julia> isprimitivetype(typeof(1.0)) # Float64
true

julia> isprimitivetype(typeof(1)) # Int64
true

julia> isprimitivetype(typeof((1.0,2.0))) # Tuple{Float64, Float64}
false

julia> isprimitivetype(typeof("a")) # String
false

julia> isprimitivetype(typeof('a')) # Char
true

```

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [January 1, 2019, 2:12pm UTC](https://discourse.julialang.org/t/how-to-detect-if-an-object-is-a-user-defined-struct/19165/5 "2019-01-01T14:12:43Z")

</div>

It might help to get at which meaning of this you want by asking: what should happen on the future if Julia introduces a new predefined type? Would your code break if that was included or if it wasn’t?

---

<div class="post-metadata">

**Author:** ![Ferran\_Mazzanti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ferran_mazzanti/32/7458_2.png) [@Ferran\_Mazzanti](https://discourse.julialang.org/u/Ferran_Mazzanti)\
**Post date:** [January 2, 2019, 12:41pm UTC](https://discourse.julialang.org/t/how-to-detect-if-an-object-is-a-user-defined-struct/19165/6 "2019-01-02T12:41:58Z")

</div>

Maybe I can put things in a different way. I have user-defined objects that have other user-defined objects as some of its fields, ex

```julia
mutable struct krok
   x :: Int64
   y :: Float64
   krok() = new()
end

mutable struct reptil
   a :: Int64
   b :: krok
   reptil() = new()
end

```

such that I declare

```julia
z = krok()
z.x = 1
z.y = 3.1416

R = reptil()
R.a = 0
R.b = z

```

Then the idea is that the function, when passed R as an argument, must print R.a and call itself over R:b to print its contents, stored in z.

Somehow I have the impression I can inspect R with fieldnames()

```julia
fieldnames(typeof(R.a))
> ()
fieldnames(typeof(R.b))
> (::x, ::y)

```

so inspecting whether the list is empty or not I know if I must recursively call the function.  
The problem I don’t know how to sort out is that, when passed R to a function, fieldnames() does not provide the complete names of the variable passed to it

```julia
function dale(z)
fieldnames(typeof(z))
end

dale(R)
> (::a,::b)

```

but in that case, what I get is Symbols, and their length is always 0.

Can on easily get filenames)=, acting on z in function dale(z), to give the whole name of the original argument passed to it (R in dale(R)), so that I can check the length of the fields?

Thx and sorry for the messy post,

Ferran.

---

<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:** [January 2, 2019, 1:10pm UTC](https://discourse.julialang.org/t/how-to-detect-if-an-object-is-a-user-defined-struct/19165/7 "2019-01-02T13:10:00Z")

</div>

I don’t understand what `filenames` does.

Did you mean `fieldnames`? In what way does it not work?

It would be better if you described what you are trying to achieve.

---

<div class="post-metadata">

**Author:** ![Ferran\_Mazzanti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ferran_mazzanti/32/7458_2.png) [@Ferran\_Mazzanti](https://discourse.julialang.org/u/Ferran_Mazzanti)\
**Post date:** [January 2, 2019, 2:01pm UTC](https://discourse.julialang.org/t/how-to-detect-if-an-object-is-a-user-defined-struct/19165/8 "2019-01-02T14:01:12Z")

</div>

Sorry, yes… it was fieldnames(). Just copied and pasted the wrong thing many times ☹

---

<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 2, 2019, 3:06pm UTC](https://discourse.julialang.org/t/how-to-detect-if-an-object-is-a-user-defined-struct/19165/9 "2019-01-02T15:06:19Z")

</div>

Please accurately define what do you meman by “user-defined struct”. Is a type defined in `Base` module one? What about one defined in a stdlib package? What about a third party package? Does it only belong to a few packages you are interested in? Does it have to be from a script (i.e. from `Main`)? Does it have to be a type you defines? Or maybe it could be a type that others could define that satisfy some properties? If so, what are those properties, can you just test those instead?  
Is being a `struct` the only important feature? (i.e. you want to test if it’s a primitive type).

Also related is do you care about the field type or the field value. That determines if you need to handle abstract type.

You see, every single questions I raise above should have a well defined and relatively simple answer that you can easily code out. From your `krok`, `reptil` example, however, it’s unclear what about those types are so special that you need to recurse into them. In general, if what makes them special is some general concept of the type, then you just test that after figuring out **what** it is (see above). Otherwise, you are interested in some property that’s only interesting for you (which is the most common and most useful case BTW) and you need to encode that info yourself, say by either inherit them from the same abstract type, or (possibly combined with abstract type) specializing your “function” (for printing??) on these types.

P.S. are you sure you are not just looking for `show`?

---

<div class="post-metadata">

**Author:** ![Ferran\_Mazzanti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ferran_mazzanti/32/7458_2.png) [@Ferran\_Mazzanti](https://discourse.julialang.org/u/Ferran_Mazzanti)\
**Post date:** [January 2, 2019, 8:43pm UTC](https://discourse.julialang.org/t/how-to-detect-if-an-object-is-a-user-defined-struct/19165/10 "2019-01-02T20:43:59Z")

</div>

Too many questions 🙂  
I guess, at least for a start, that the data types I will be using are those created by me and only me in my codes, a type defined by me. No packages, no nothing else. So it is the ‘some property that’s only interesting for you (which is the most common and most useful case BTW)’, in your own words…  
Thx  
Ferran.

---

<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 2, 2019, 9:13pm UTC](https://discourse.julialang.org/t/how-to-detect-if-an-object-is-a-user-defined-struct/19165/11 "2019-01-02T21:13:48Z")

</div>

> [@Ferran\_Mazzanti](#):
>
> I guess, at least for a start, that the data types I will be using are those created by me and only me in my codes, a type defined by me. No packages, no nothing else.

I highly doubt if this is actually the property you are interested in, by which I mean, you (the programmer) might be interested in it but in general code (written by you) shouldn’t really care about it’s author. Having your friend fixing a typo in your code will change the (co)author of the code but shouldn’t change the code’s behavior in a way that’s different if you made the change yourself. There’s just no way this can happen with current computer technology.

> [@Ferran\_Mazzanti](#):
>
> So it is the ‘some property that’s only interesting for you

I should clarify this as “objective property” or “code property”. Anything that your **code** can react to, rather than anything that is intersting to you for other reason…

> [@Ferran\_Mazzanti](#):
>
> Too many questions 🙂

I give you a long list since it’s AFAICT the simplest way to guide yourself to the definition of your “user-defined struct”. It’s also to help you to formulate your question in a way that others can actually help. Otherwise there are only guesses and that’s what I’m going to do below too.

The closest interpretation of what you said I can come up with is that you want to treat types in your script differently than anything else. You are not using any packages. In that case, it’s included in my list of questions above and, well, just test if the type is from Main should work for you, i.e. `T.name.module === Main`. Note that this will break if you move the code. Change `Main` to `@ __MODULE__ ` will work if you put it in a module. It’s still a property that makes no sense to query other than for some low level purposes. In particular, it’s orthogonal to whether the type has field to be iterated, which is what you want to do, so making the decision this way is almost certainly wrong.

If you don’t care too much about the maintainability of the code, you can just hard code the list of special types for you, which is actually a much better method in many ways. OTOH, if you want an answer with a more maintainable approach that makes more sense, you really need a definition of “user-defined struct” that is actually based on some programatically distinguishable properties. Again, the list I have above should be a good place to start.

---

<div class="post-metadata">

**Author:** ![Ferran\_Mazzanti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ferran_mazzanti/32/7458_2.png) [@Ferran\_Mazzanti](https://discourse.julialang.org/u/Ferran_Mazzanti)\
**Post date:** [January 2, 2019, 9:23pm UTC](https://discourse.julialang.org/t/how-to-detect-if-an-object-is-a-user-defined-struct/19165/12 "2019-01-02T21:23:51Z")

</div>

Thanks for the info but… honestly, you’re making a mess out of the question. The situation I want to solve _now_ is not a general case, it is as simple as the kook() and reptile() case above, defined by me and used by me. Nothing fancy, nothing that should care too many people…

---

<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 2, 2019, 9:32pm UTC](https://discourse.julialang.org/t/how-to-detect-if-an-object-is-a-user-defined-struct/19165/13 "2019-01-02T21:32:03Z")

</div>

> [@Ferran\_Mazzanti](#):
>
> you’re making a mess out of the question

OK?

> [@Ferran\_Mazzanti](#):
>
> it is as simple as the kook() and reptile() case above

OK, in that case and if you don’t want to read any one of my potential implementations above, for which I have at least 3, just define your function to treat `kook` and `reptile` type differently. That’s as simple as it gets.

> [@Ferran\_Mazzanti](#):
>
> The situation I want to solve _now_ is not a general case

Edit: Then update your title please. Your title is very generic. It doesn’t mention `kook` or `reptile` specifically. If the example you gave are not examples of a more general question but actually the question itself, please clarify.

---

<div class="post-metadata">

**Author:** ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)\
**Post date:** [January 2, 2019, 9:34pm UTC](https://discourse.julialang.org/t/how-to-detect-if-an-object-is-a-user-defined-struct/19165/14 "2019-01-02T21:34:01Z")

</div>

I think it could be helpful if you could show us the precise input and corresponding output you’re looking for. Perhaps something along these lines? Otherwise please clarify.

```julia
struct Animal
   name::String
   count::Int
end

struct Reptil
   name::String
   parent::Animal
   count::Int
end

struct Krok
   name::String
   age::Int
   parent::Reptil
end

inspect(r, _) = print(r)

function inspect(r::Union{Krok,Reptil,Animal}, padding = 0)
   print(typeof(r))
   for f in fieldnames(typeof(r))
      print("\n" * " "^(padding+2) * "$f = ")
      inspect(getfield(r, f), padding + 2)
   end
end

animals = Animal("All animals", 1_000_000)
reptiles = Reptil("Reptiles", animals, 10_000)
krok = Krok("My crocodile", 42, reptiles)

inspect(krok)

```

Output:

```julia
Krok
  name = My crocodile
  age = 42
  parent = Reptil
    name = Reptiles
    parent = Animal
      name = All animals
      count = 1000000
    count = 10000

```

---

<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 2, 2019, 9:42pm UTC](https://discourse.julialang.org/t/how-to-detect-if-an-object-is-a-user-defined-struct/19165/15 "2019-01-02T21:42:24Z")

</div>

> [@bennedich](#):
>
> function inspect(r::Union{Krok,Reptil,Animal}, padding = 0)

That’s why I mentioned [`show`](https://github.com/JuliaLang/julia/blob/356ceeee0170e41ac109abc0841d394f5472c5e7/base/show.jl#L315-L350)

Also the similarly defined [`dump`](https://github.com/JuliaLang/julia/blob/356ceeee0170e41ac109abc0841d394f5472c5e7/base/show.jl#L1613-L1640)

---

<div class="post-metadata">

**Author:** ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)\
**Post date:** [January 2, 2019, 9:49pm UTC](https://discourse.julialang.org/t/how-to-detect-if-an-object-is-a-user-defined-struct/19165/16 "2019-01-02T21:49:42Z")

</div>

> [@yuyichao](#):
>
> That’s why I mentioned [`show`](https://github.com/JuliaLang/julia/blob/356ceeee0170e41ac109abc0841d394f5472c5e7/base/show.jl#L315-L350)

I know, I liked your comment above after you posted it, but thought OP would appreciate the help implementing it, especially the part about customizing behavior for his own types.

---

<div class="post-metadata">

**Author:** ![Ferran\_Mazzanti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ferran_mazzanti/32/7458_2.png) [@Ferran\_Mazzanti](https://discourse.julialang.org/u/Ferran_Mazzanti)\
**Post date:** [January 3, 2019, 10:26am UTC](https://discourse.julialang.org/t/how-to-detect-if-an-object-is-a-user-defined-struct/19165/17 "2019-01-03T10:26:56Z")

</div>

Thank you all for the replies…  
And Bennedicich, thanks for the code which almost suits a preliminary form of what I’d like to have. Your code works great for the case example but when I remove the

```julia
Union{Krok,Reptil,Animal}

```

form the definition of the function and leave it as

```julia
function inspect(r, padding = 0)

```

the output I get is

```julia
Krok
  name = String
  age = Int64
  parent = Reptil
    name = String
    parent = Animal
      name = String
      count = Int64
    count = Int64

z = show(krok)

```

I removed the Union because I do not want to restrict the function to this case, and I don’t want to list all my structs as I have many… would that have a simple fix?

Thanks again,

Ferran.

---

<div class="post-metadata">

**Author:** ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)\
**Post date:** [January 3, 2019, 1:58pm UTC](https://discourse.julialang.org/t/how-to-detect-if-an-object-is-a-user-defined-struct/19165/18 "2019-01-03T13:58:17Z")

</div>

Yes there’s a simple fix, by looking at which module the type is defined in. (Again, the answer has already been posted above.) Replace the two `inspect` methods with:

```julia
function inspect(r, padding = 0)
   parentmodule(typeof(r)) ≡ Main || return print(r) # not user-defined

   # user-defined type
   print(typeof(r))
   for f in fieldnames(typeof(r))
      print("\n" * " "^(padding+2) * "$f = ")
      inspect(getfield(r, f), padding + 2)
   end
end

```

Note: This is just a proof-of-concept. You’ll need to replace `Main` above with whatever module your types are defined in, and if you have hierarchical modules you’ll need to add support for that.
