In a fresh R session, I created a promise z
, the vectors x
and y
, and a function obj.info
.
delayedAssign("z", logical(5))
x <- 1:100
y <- rnorm(4e3L)
obj.info <- function(envir = .GlobalEnv){
ls <- ls(envir)
obj <- sapply(ls, get)
FUN <- function(x){
c(type = class(x), length = length(x), size = object.size(x))
}
noquote(t(sapply(obj, FUN)))
}
In RStudio, the Global Environment table is as expected, with the unevaluated promise included.
This is exactly what I want to duplicate
A call to obj.info()
returns the following table.
obj.info()
# type length size
# obj.info function 1 13872
# x integer 100 440
# y numeric 4000 32040
# z logical 5 72
The problem is that z
has been evaluated in the process, and I didn't want that to happen quite yet. All I want is the information about z
.
At first, I figured get
was causing this, but evaluation of z
also occurs if I call class
on the ls()
objects before calling get
. The result I want has
# z promise 0 0
for the promised object z
.
Is the table in the RStudio window something is easily accessible from the console? And if so, can we get it without evaluating z
? Something like the following ls.str
table (and others) that can be deparsed would be ideal.
capture.output(ls.str())
# [1] "obj.info : function (envir = .GlobalEnv) "
# [2] "x : int [1:100] 1 2 3 4 5 6 7 8 9 10 ..."
# [3] "y : num [1:4000] -0.277 -0.431 -0.143 -0.218 -0.846 ..."
# [4] "z : logi [1:5] FALSE FALSE FALSE FALSE FALSE"
Or even if there's a way to run this condition through an if
statement, something like
if( x is a promise ) { do not evaluate it, but get its information }
I'm running RStudio Version 0.98.994
Hadley has a simple Rcpp implementation of the relevant code in his pryr library.
The relevant code snippet is:
// [[Rcpp::export]]
bool is_promise2(Symbol name, Environment env) {
SEXP object = Rf_findVar(name, env);
return (TYPEOF (object) == PROMSXP);
}
// [[Rcpp::export]]
SEXP promise_code(Symbol name, Environment env) {
SEXP object = Rf_findVar(name, env);
return PRCODE(object);
}
// [[Rcpp::export]]
SEXP promise_value(Symbol name, Environment env) {
SEXP object = Rf_findVar(name, env);
return PRVALUE(object);
}
Here’s how this can be used:
Rcpp::sourceCpp('promise.cpp')
delayedAssign("z", logical(5))
is_promise2('z', environment())
# [1] TRUE
promise_code('y', environment())
# logical(5)
However, sourceCpp
always recompiles the code, which is inefficient. Rcpp sources are normally used as part of a package.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With