lobstr/ 0000755 0001762 0000144 00000000000 14254721642 011566 5 ustar ligges users lobstr/NAMESPACE 0000644 0001762 0000144 00000001161 14254621577 013012 0 ustar ligges users # Generated by roxygen2: do not edit by hand
S3method("[",lobstr_bytes)
S3method(c,lobstr_bytes)
S3method(format,lobstr_bytes)
S3method(format,lobstr_inspector)
S3method(print,lobstr_bytes)
S3method(print,lobstr_inspector)
S3method(print,lobstr_raw)
S3method(tree_label,"NULL")
S3method(tree_label,"function")
S3method(tree_label,character)
S3method(tree_label,default)
S3method(tree_label,environment)
export(ast)
export(cst)
export(mem_used)
export(obj_addr)
export(obj_addrs)
export(obj_size)
export(obj_sizes)
export(ref)
export(sxp)
export(tree)
export(tree_label)
import(rlang)
useDynLib(lobstr, .registration = TRUE)
lobstr/LICENSE 0000644 0001762 0000144 00000000054 14032635514 012566 0 ustar ligges users YEAR: 2020
COPYRIGHT HOLDER: lobstr authors
lobstr/README.md 0000644 0001762 0000144 00000004374 14254675357 013070 0 ustar ligges users
# lobstr
[](https://cran.r-project.org/package=lobstr)
[](https://github.com/r-lib/lobstr/actions/workflows/R-CMD-check.yaml)
[](https://app.codecov.io/gh/r-lib/lobstr?branch=main)
lobstr provides tools in the same vein as `str()`, which allow you to
dig into the detail of an object.
## Installation
Install the released version of lobstr from CRAN:
``` r
install.packages("lobstr")
```
You can install the development version with:
``` r
# install.packages("devtools")
devtools::install_github("r-lib/lobstr")
```
## Example
### Abstract syntax trees
`ast()` draws the abstract syntax tree of R expressions:
``` r
ast(a + b + c)
#> █─`+`
#> ├─█─`+`
#> │ ├─a
#> │ └─b
#> └─c
ast(function(x = 1) {
if (x > 0) print("Hi!")
})
#> █─`function`
#> ├─█─x = 1
#> ├─█─`{`
#> │ └─█─`if`
#> │ ├─█─`>`
#> │ │ ├─x
#> │ │ └─0
#> │ └─█─print
#> │ └─"Hi!"
#> └─
```
### References
`ref()` shows hows objects can be shared across data structures by
digging into the underlying \_\_ref\_\_erences:
``` r
x <- 1:1e6
y <- list(x, x, x)
ref(y)
#> █ [1:0x7fed114eaea8]
#> ├─[2:0x7fed21f373b8]
#> ├─[2:0x7fed21f373b8]
#> └─[2:0x7fed21f373b8]
e <- rlang::env()
e$self <- e
ref(e)
#> █ [1:0x7fecf1856f00]
#> └─self = [1:0x7fecf1856f00]
```
A related tool is `obj_size()`, which computes the size of an object
taking these shared references into account:
``` r
obj_size(x)
#> 680 B
obj_size(y)
#> 760 B
```
### Call stack trees
`cst()` shows how frames on the call stack are connected:
``` r
f <- function(x) g(x)
g <- function(x) h(x)
h <- function(x) x
f(cst())
#> ▆
#> 1. ├─global f(cst())
#> 2. │ └─global g(x)
#> 3. │ └─global h(x)
#> 4. └─lobstr::cst()
```
lobstr/man/ 0000755 0001762 0000144 00000000000 14254716056 012344 5 ustar ligges users lobstr/man/obj_size.Rd 0000644 0001762 0000144 00000005133 13477777720 014454 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/size.R
\name{obj_size}
\alias{obj_size}
\alias{obj_sizes}
\title{Calculate the size of an object.}
\usage{
obj_size(..., env = parent.frame())
obj_sizes(..., env = parent.frame())
}
\arguments{
\item{...}{Set of objects to compute size.}
\item{env}{Environment in which to terminate search. This defaults to the
current environment so that you don't include the size of objects that
are already stored elsewhere.
Regardless of the value here, \code{obj_size()} never looks past the
global or base environments.}
}
\value{
An estimate of the size of the object, in bytes.
}
\description{
\code{obj_size()} computes the size of an object or set of objects;
\code{obj_sizes()} breaks down the individual contribution of multiple objects
to the total size.
}
\section{Compared to \code{object.size()}}{
Compared to \code{\link[=object.size]{object.size()}}, \code{obj_size()}:
\itemize{
\item Accounts for all types of shared values, not just strings in
the global string pool.
\item Includes the size of environments (up to \code{env})
\item Accurately measures the size of ALTREP objects.
}
}
\section{Environments}{
\code{obj_size()} attempts to take into account the size of the
environments associated with an object. This is particularly important
for closures and formulas, since otherwise you may not realise that you've
accidentally captured a large object. However, it's easy to over count:
you don't want to include the size of every object in every environment
leading back to the \code{\link[=emptyenv]{emptyenv()}}. \code{obj_size()} takes
a heuristic approach: it never counts the size of the global environment,
the base environment, the empty environment, or any namespace.
Additionally, the \code{env} argument allows you to specify another
environment at which to stop. This defaults to the environment from which
\code{obj_size()} is called to prevent double-counting of objects created
elsewhere.
}
\examples{
# obj_size correctly accounts for shared references
x <- runif(1e4)
obj_size(x)
z <- list(a = x, b = x, c = x)
obj_size(z)
# this means that object size is not transitive
obj_size(x)
obj_size(z)
obj_size(x, z)
# use obj_size() to see the unique contribution of each component
obj_sizes(x, z)
obj_sizes(z, x)
obj_sizes(!!!z)
# obj_size() also includes the size of environments
f <- function() {
x <- 1:1e4
a ~ b
}
obj_size(f())
#' # In R 3.5 and greater, `:` creates a special "ALTREP" object that only
# stores the first and last elements. This will make some vectors much
# smaller than you'd otherwise expect
obj_size(1:1e6)
}
lobstr/man/sxp.Rd 0000644 0001762 0000144 00000003757 13762501764 013462 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/sxp.R
\name{sxp}
\alias{sxp}
\title{Inspect an object}
\usage{
sxp(x, expand = character(), max_depth = 5L)
}
\arguments{
\item{x}{Object to inspect}
\item{expand}{Optionally, expand components of the true that are usually
suppressed. Use:
\itemize{
\item "character" to show underlying entries in the global string pool.
\item "environment" to show the underlying hashtables.
\item "altrep" to show the underlying data.
\item "call" to show the full AST (but \code{\link[=ast]{ast()}} is usually superior)
\item "bytecode" to show generated bytecode.
}}
\item{max_depth}{Maximum depth to recurse. Use \code{max_depth = Inf} (with care!)
to recurse as deeply as possible. Skipped elements will be shown as \code{...}.`}
}
\description{
\code{sxp(x)} is similar to \code{.Internal(inspect(x))}, recursing into the C data
structures underlying any R object. The main difference is the output is a
little more compact, it recurses fully, and avoids getting stuck in infinite
loops by using a depth-first search. It also returns a list that you can
compute with, and carefully uses colour to highlight the most important
details.
}
\details{
The name \code{sxp} comes from \code{SEXP}, the name of the C data structure that
underlies all R objects.
}
\examples{
x <- list(
TRUE,
1L,
runif(100),
"3"
)
sxp(x)
# Expand "character" to see underlying CHARSXP entries in the global
# string pool
x <- c("banana", "banana", "apple", "banana")
sxp(x)
sxp(x, expand = "character")
# Expand altrep to see underlying data
x <- 1:10
sxp(x)
sxp(x, expand = "altrep")
# Expand environmnets to see the underlying implementation details
e1 <- new.env(hash = FALSE, parent = emptyenv(), size = 3L)
e2 <- new.env(hash = TRUE, parent = emptyenv(), size = 3L)
e1$x <- e2$x <- 1:10
sxp(e1)
sxp(e1, expand = "environment")
sxp(e2, expand = "environment")
}
\seealso{
Other object inspectors:
\code{\link{ast}()},
\code{\link{ref}()}
}
\concept{object inspectors}
lobstr/man/cst.Rd 0000644 0001762 0000144 00000002127 13304255332 013414 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/cst.R
\name{cst}
\alias{cst}
\title{Call stack tree}
\usage{
cst()
}
\description{
Shows the relationship between calls on the stack. This function
combines the results of \code{\link[=sys.calls]{sys.calls()}} and \code{\link[=sys.parents]{sys.parents()}} yielding a display
that shows how frames on the call stack are related.
}
\examples{
# If all evaluation is eager, you get a single tree
f <- function() g()
g <- function() h()
h <- function() cst()
f()
# You get multiple trees with delayed evaluation
try(f())
# Pay attention to the first element of each subtree: each
# evaluates the outermost call
f <- function(x) g(x)
g <- function(x) h(x)
h <- function(x) x
try(f(cst()))
# With a little ingenuity you can use it to see how NSE
# functions work in base R
with(mtcars, {cst(); invisible()})
invisible(subset(mtcars, {cst(); cyl == 0}))
# You can also get unusual trees by evaluating in frames
# higher up the call stack
f <- function() g()
g <- function() h()
h <- function() eval(quote(cst()), parent.frame(2))
f()
}
lobstr/man/tree.Rd 0000644 0001762 0000144 00000005634 14253140421 013564 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/tree.R
\name{tree}
\alias{tree}
\title{Pretty tree-like object printing}
\usage{
tree(
x,
...,
index_unnamed = FALSE,
max_depth = 10L,
max_length = 1000L,
show_environments = TRUE,
hide_scalar_types = TRUE,
val_printer = crayon::blue,
class_printer = crayon::silver,
show_attributes = FALSE,
remove_newlines = TRUE,
tree_chars = box_chars()
)
}
\arguments{
\item{x}{A tree like object (list, etc.)}
\item{...}{Ignored (used to force use of names)}
\item{index_unnamed}{Should children of containers without names have indices
used as stand-in?}
\item{max_depth}{How far down the tree structure should be printed. E.g. \code{1}
means only direct children of the root element will be shown. Useful for
very deep lists.}
\item{max_length}{How many elements should be printed? This is useful in case
you try and print an object with 100,000 items in it.}
\item{show_environments}{Should environments be treated like normal lists and
recursed into?}
\item{hide_scalar_types}{Should atomic scalars be printed with type and
length like vectors? E.g. \code{x <- "a"} would be shown as \verb{x: "a"}
instead of \code{x: "a"}.}
\item{val_printer}{Function that values get passed to before being drawn to
screen. Can be used to color or generally style output.}
\item{class_printer}{Same as \code{val_printer} but for the the class types of
non-atomic tree elements.}
\item{show_attributes}{Should attributes be printed as a child of the list or
avoided?}
\item{remove_newlines}{Should character strings with newlines in them have
the newlines removed? Not doing so will mess up the vertical flow of the
tree but may be desired for some use-cases if newline structure is
important to understanding object state.}
\item{tree_chars}{List of box characters used to construct tree. Needs
elements \verb{$h} for horizontal bar, \verb{$hd} for dotted horizontal bar, \verb{$v} for
vertical bar, \verb{$vd} for dotted vertical bar, \verb{$l} for l-bend, and \verb{$j} for
junction (or middle child).}
}
\value{
console output of structure
}
\description{
A cleaner and easier to read replacement for \code{str} for nested list-like
objects
}
\examples{
x <- list(
list(id = "a", val = 2),
list(
id = "b",
val = 1,
children = list(
list(id = "b1", val = 2.5),
list(
id = "b2",
val = 8,
children = list(
list(id = "b21", val = 4)
)
)
)
),
list(
id = "c",
val = 8,
children = list(
list(id = "c1"),
list(id = "c2", val = 1)
)
)
)
# Basic usage
tree(x)
# Even cleaner output can be achieved by not printing indices
tree(x, index_unnamed = FALSE)
# Limit depth if object is potentially very large
tree(x, max_depth = 2)
# You can customize how the values and classes are printed if desired
tree(x, val_printer = function(x) {
paste0("_", x, "_")
})
}
lobstr/man/mem_used.Rd 0000644 0001762 0000144 00000001237 13251236036 014423 0 ustar ligges users % Generated by roxygen2: do not edit by hand
% Please edit documentation in R/mem.R
\name{mem_used}
\alias{mem_used}
\title{How much memory is currently used by R?}
\usage{
mem_used()
}
\description{
\code{mem_used()} wraps around \code{gc()} and returns the exact number of bytes
currently used by R. Note that changes will not match up exactly to
\code{\link[=obj_size]{obj_size()}} as session specific state (e.g. \link{.Last.value}) adds minor
variations.
}
\examples{
prev_m <- 0; m <- mem_used(); m - prev_m
x <- 1:1e6
prev_m <- m; m <- mem_used(); m - prev_m
obj_size(x)
rm(x)
prev_m <- m; m <- mem_used(); m - prev_m
prev_m <- m; m <- mem_used(); m - prev_m
}
lobstr/man/figures/ 0000755 0001762 0000144 00000000000 13406770053 014003 5 ustar ligges users lobstr/man/figures/logo.png 0000644 0001762 0000144 00000067477 13406770053 015476 0 ustar ligges users PNG
IHDR X? gAMA a cHRM z&