# Given an object, return Julia code that defines the object

**URL:** <https://discourse.julialang.org/t/given-an-object-return-julia-code-that-defines-the-object/80579>\
**Category:** General Usage\
**Created:** [May 5, 2022, 11:59pm UTC](https://discourse.julialang.org/t/given-an-object-return-julia-code-that-defines-the-object/80579 "2022-05-05T23:59:28Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ashlin\_Harris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashlin_harris/32/210166_2.png) [@Ashlin\_Harris](https://discourse.julialang.org/u/Ashlin_Harris)\
**Post date:** [May 5, 2022, 11:59pm UTC](https://discourse.julialang.org/t/given-an-object-return-julia-code-that-defines-the-object/80579/1 "2022-05-05T23:59:28Z")

</div>

Is there a function or macro that accepts an object and returns the Julia code that defines the object? For instance, is there a function `f()` with the following behaviour?

```julia
julia> X=Dict([("A", 1), ("B", 2)])
Dict{String, Int64} with 2 entries:
  "B" => 2
  "A" => 1
julia> f(X)
Dict([("A", 1), ("B", 2)])
julia>eval(f(X))
Dict{String, Int64} with 2 entries:
  "B" => 2
  "A" => 1

```

My use case is software regression testing, so any alternative for recovering a definition from a value is welcome.

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [May 6, 2022, 12:12am UTC](https://discourse.julialang.org/t/given-an-object-return-julia-code-that-defines-the-object/80579/2 "2022-05-06T00:12:50Z")

</div>

uhh, depends on what you mean.

1. If you mean _I want an already assembled call to the default constructor_, then `show(X)` gives you `Dict("B" => 2,"A" => 1)` in your example.
2. If you mean _I want to recover the exact way this object was constructed or the line this happened_, no. I do not believe this is easy to achieve and, in fact, it may be impossible.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [May 6, 2022, 12:13am UTC](https://discourse.julialang.org/t/given-an-object-return-julia-code-that-defines-the-object/80579/3 "2022-05-06T00:13:00Z")

</div>

try this:

```julia
julia> repr(x)
"Dict(\"B\" => 2, \"A\" => 1)"

julia> Meta.parse(repr(x))
:(Dict("B" => 2, "A" => 1))

julia> eval(Meta.parse(repr(x)))
Dict{String, Int64} with 2 entries:
  "B" => 2
  "A" => 1

```

in general `repr` is designed such that if you copy paste it into REPL it would work, but this is not guaranteed.

As you can see already, because there exist multiple way to construct identical `Dict()`, you can’t inverse the process.

Are you sure this is not a XY problem? what is that you want to test?

---

<div class="post-metadata">

**Author:** ![Ashlin\_Harris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashlin_harris/32/210166_2.png) [@Ashlin\_Harris](https://discourse.julialang.org/u/Ashlin_Harris)\
**Post date:** [May 6, 2022, 12:22am UTC](https://discourse.julialang.org/t/given-an-object-return-julia-code-that-defines-the-object/80579/4 "2022-05-06T00:22:47Z")

</div>

Option 1 is sufficient. I just need a way to reproduce the result, not recover the history. `show()` works for dictionaries, but not for other objects like DataFrames. For these, it behaves more like `display`, which gives a human-readable (but not Julia-readable) version.

---

<div class="post-metadata">

**Author:** ![Ashlin\_Harris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashlin_harris/32/210166_2.png) [@Ashlin\_Harris](https://discourse.julialang.org/u/Ashlin_Harris)\
**Post date:** [May 6, 2022, 12:26am UTC](https://discourse.julialang.org/t/given-an-object-return-julia-code-that-defines-the-object/80579/5 "2022-05-06T00:26:29Z")

</div>

I am writing a function that manipulates DataFrames. A better example might be:

```julia
julia> Y=DataFrame(a=[1,2,3],b=['q','r','s'])
3×2 DataFrame
 Row │ a b    
     │ Int64 Char 
─────┼─────────────
   1 │ 1 q
   2 │ 2 r
   3 │ 3 s

julia> Y[!,:c] = [true, true, false];

julia> show(Y)
3×3 DataFrame
 Row │ a b c     
     │ Int64 Char Bool  
─────┼────────────────────
   1 │ 1 q true
   2 │ 2 r true
   3 │ 3 s false

```

I am looking for a function with this behaviour:

```julia
julia> f(Y)
DataFrame(a=[1,2,3],b=['q','r','s'],c=[true, true, false])

```

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [May 6, 2022, 12:27am UTC](https://discourse.julialang.org/t/given-an-object-return-julia-code-that-defines-the-object/80579/6 "2022-05-06T00:27:04Z")

</div>

but why? what is the property you can’t test without a string that evaluates to some dataframe you already have?

---

<div class="post-metadata">

**Author:** ![Ashlin\_Harris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashlin_harris/32/210166_2.png) [@Ashlin\_Harris](https://discourse.julialang.org/u/Ashlin_Harris)\
**Post date:** [May 6, 2022, 12:29am UTC](https://discourse.julialang.org/t/given-an-object-return-julia-code-that-defines-the-object/80579/7 "2022-05-06T00:29:43Z")

</div>

There is none. As a workaround, I could type out the definition myself. I am curious if there is some way to generate this automatically. This would be helpful for much larger structures.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [May 6, 2022, 12:32am UTC](https://discourse.julialang.org/t/given-an-object-return-julia-code-that-defines-the-object/80579/8 "2022-05-06T00:32:55Z")

</div>

> [@Ashlin\_Harris](#):
>
> I could type out the definition myself

I’m confused, I thought you already have an object in the flow of your program, that you want to invert back to String.

does the functionality you’re testing manipulate the source code string itself??

---

<div class="post-metadata">

**Author:** ![Ashlin\_Harris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashlin_harris/32/210166_2.png) [@Ashlin\_Harris](https://discourse.julialang.org/u/Ashlin_Harris)\
**Post date:** [May 6, 2022, 12:36am UTC](https://discourse.julialang.org/t/given-an-object-return-julia-code-that-defines-the-object/80579/9 "2022-05-06T00:36:08Z")

</div>

The function I write will generate the object. However, I am software regression testing, so I want to make sure that the output stays the same between versions. So, I’d like to save the output from a previous version. Test cases might involve very large data frames, so it isn’t feasible to type out the definition of the intended output. One workaround might be to compare the test display of the DataFramse using `show()`, but I’d like to directly compare DataFrames for equality.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [May 6, 2022, 12:37am UTC](https://discourse.julialang.org/t/given-an-object-return-julia-code-that-defines-the-object/80579/10 "2022-05-06T00:37:12Z")

</div>

> [@Ashlin\_Harris](#):
>
> make sure that the output stays the same between versions

just save the output to a string, re-direct `stdout`, and compare? this is a very common test in Julia

> <https://github.com/JuliaLang/julia/commit/68c71f577275a16fffb743b2058afdc2d635068f#diff-b44eebf66a97ac0a68b21f779e752f2f3b59063151bb90e92802c49eb58ebd4bR973>
>
> The \`verbose\` option in \`@testset\` can be used to print the results
> of the chil…d tests, even when all of them have passed.
> 
> Closes #27088

how else are you gonna test across versions? if you use some auto generation, such as `repr`, supposedly it will always equal to the other end of the equality right? namely, the current `repr` you want to test.

so you always have to hard-code previous, known good output – isn’t that the whole point?

---

<div class="post-metadata">

**Author:** ![Ashlin\_Harris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashlin_harris/32/210166_2.png) [@Ashlin\_Harris](https://discourse.julialang.org/u/Ashlin_Harris)\
**Post date:** [May 6, 2022, 12:49am UTC](https://discourse.julialang.org/t/given-an-object-return-julia-code-that-defines-the-object/80579/11 "2022-05-06T00:49:18Z")

</div>

Thanks, this should be sufficient. Still, I’d prefer to hard code two DataFrame definitions rather than hard code the text output from the display. Since Julia is homoiconic, I’d be interested in seeing a version of `repr()` or `show()` that handles a DataFrame the way a Dict is handled. I’ll accept your answer if I can’t find something like that. Many thanks!

---

<div class="post-metadata">

**Author:** ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)\
**Post date:** [May 6, 2022, 1:11am UTC](https://discourse.julialang.org/t/given-an-object-return-julia-code-that-defines-the-object/80579/12 "2022-05-06T01:11:16Z")

</div>

```julia
julia> let df = DataFrame(a=[1]); invoke(show, Tuple{typeof(stdout), Any}, stdout, df) end
DataFrame(AbstractVector[[1]], DataFrames.Index(Dict(:a => 1), [:a]))

```

DataFrames.jl could probably make this easier, perhaps with `repr` . cc @bkamins
