Closed nstrayer closed 3 years ago
Fixes #2. Should we call it rst()
?
Does rst
stand for anything or is it just an anagram of str
?
@wch ooops I meant rts()
which standards for restricted tree structure. I think that pairs nicely with ast()
, ref()
, sxp()
.
What about having it as rts
with a longer formed alias of tree
or something like that for people like me who can never remember acronym names like that?
For environments, this should print out something sensible:
A <- R6::R6Class("A",
public = list(getx = function() private$x),
private = list(x = 1)
)
a <- A$new()
lobstr::tree(a)
Currently it seems to repeat the same information a bunch of times:
<environment: 0x7fe909664dd8>
├─.__enclos_env__: <environment: 0x7fe909665120>
│ ├─private: <environment: 0x7fe909664a58>
│ │ └─x: 1
│ └─self: <environment: 0x7fe909664dd8>
│ ├─.__enclos_env__: <environment: 0x7fe909665120>
│ │ ├─private: <environment: 0x7fe909664a58>
│ │ │ └─x: 1
│ │ └─self: <environment: 0x7fe909664dd8>
│ │ ├─.__enclos_env__: <environment: 0x7fe909665120>
│ │ │ ├─private: <environment: 0x7fe909664a58>
│ │ │ │ └─x: 1
│ │ │ └─self: <environment: 0x7fe909664dd8>
│ │ │ ├─.__enclos_env__: <environment: 0x7fe909665120>
│ │ │ │ ├─private: <environment: 0x7fe909664a58>
│ │ │ │ │ └─x: 1
│ │ │ │ └─self: <environment: 0x7fe909664dd8>
│ │ │ │ ├─.__enclos_env__: <environment: 0x7fe909665120>
│ │ │ │ │ ├─private: <environment: 0x7fe909664a58>
│ │ │ │ │ │ └─x: 1
│ │ │ │ │ └─self: <environment: 0x7fe909664dd8>...
│ │ │ │ ├─clone: function(){...}
│ │ │ │ └─getx: function(){...}
│ │ │ ├─clone: function(){...}
│ │ │ └─getx: function(){...}
│ │ ├─clone: function(){...}
│ │ └─getx: function(){...}
│ ├─clone: function(){...}
│ └─getx: function(){...}
├─clone: function(){...}
└─getx: function(){...}
I think it should also display classes for environments (a
is an environment with classes "A"
and "R6"
).
OTOH it might be better to leave environments off this PR, and tackle them once the main shape of the function has been merged.
I switched around the logic a bit and now the R6 example returns this: Do you still think this is too verbose?
A <- R6::R6Class("A",
public = list(getx = function() private$x),
private = list(x = 1)
)
a <- A$new()
lobstr::tree(a)
#> <environment: 0x7fc388566038>
#> ├─.__enclos_env__: <environment: 0x7fc3885665b0>
#> │ ├─private: <environment: 0x7fc388565cf0>
#> │ │ └─x: 1
#> │ └─self: <environment: 0x7fc388566038>
#> │ ├─clone: function(){...}
#> │ └─getx: function(){...}
#> ├─clone: function(){...}
#> └─getx: function(){...}```
In the tree of the R6 object, self
is the same object as the top-level R6 object, so I think you could just display something like:
<environment: 0x7fc388566038>
├─.__enclos_env__: <environment: 0x7fc3885665b0>
│ ├─private: <environment: 0x7fc388565cf0>
│ │ └─x: 1
│ └─self: <environment: 0x7fc388566038> (Already seen)
├─clone: function(){...}
└─getx: function(){...}
Removing the recusion into the parent simplified the code substantially. Here's the latest output for simple environment situations:
ea <- rlang::env(d = 4, e = 5)
eb <- rlang::env(ea, a = 1, b = 2, c = 3)
lobstr::tree(eb)
#> <environment: 0x7fcfd6fc10e0>
#> ├─a: 1
#> ├─b: 2
#> └─c: 3
A <- R6::R6Class(
"A",
public = list(getx = function() private$x),
private = list(x = 1)
)
a <- A$new()
lobstr::tree(a)
#> <environment: 0x7fcfa719a130>
#> ├─.__enclos_env__: <environment: 0x7fcfa7199ad8>
#> │ ├─private: <environment: 0x7fcfa719a4b0>
#> │ │ └─x: 1
#> │ └─self: <environment: 0x7fcfa719a130> (Already seen)
#> ├─clone: function(){...}
#> └─getx: function(){...}
@nstrayer if you fix the build failures, I think this is in a good place to merge, and we can continue iterating in future PRs.
All checks are passing -- finally! So baring name changes this should be good to go.
This PR adds the function
tree()
(and its helper functiontree_label()
.The purpose of
tree
is to replacestr()
for complex nested structures. The original inspiration was HTML tag lists with children and various other valuable information hanging off of them.Examples
Printing simple lists
Output depth can be limited to avoid information overload
You can further simplify output by avoiding printing indices for id-less elements
Prints atomic vectors inline (up to 10 elements)
Attempts to work with any list-like object.
For instance: html tag structures
Attributes can be shown (but arent by default)
You can customize the tree appearance by swapping out unicode characters
Find characters at unicode-table.com.
You can also pass custom style functions for class and value printing that transform text. E.g. using
crayon
to style.Screenshot of output in consoles with styling support.
Limitations/Drawbacks
Built entirely outside of
lobstr
at first:rlang
niceties that could make the code much more maintainable.ast()
Testing
testhat
version forlobstr
.