I am trying to turn an arbitrary chunk (not in the Rmarkdown
sense) of code into an object that I can call to return either (1) the code's output or (2) the code and its output.
I can produce output (1) by converting the code to a string and then use eval(parse())
. However, the issue with this approach is that turning the code into a string means syntax highlighters and linters do not look at the contents of the string and this makes it more difficult to debug. I am therefore looking for alternative approaches. Below I demonstrate what I'm looking for.
Start with a chunk of arbitrary code
df <- data.frame(x = 1:10)
print(5)
#> [1] 5
df$x 1
#> [1] 2 3 4 5 6 7 8 9 10 11
Current Approach: convert chunk to string
my_code <- "
df <- data.frame(x = 1:10)
print(5)
df$x 1
"
eval(parse(text = my_code))
#> [1] 5
#> [1] 2 3 4 5 6 7 8 9 10 11
Desired Approach (psuedo-code): wrap chunk in foo{}
, call object
# Wrap in some function
my_code <- foo{
df <- data.frame(x = 1:10)
print(5)
df$x 1
}
Two possible types of outputs expected
Output option #1: shows code, shows output
# Call object
my_code
df <- data.frame(x = 1:10)
print(5)
#> [1] 5
df$x 1
#> [1] 2 3 4 5 6 7 8 9 10 11
Output #2: doesn't show code, shows output
# Call object
my_code
#> [1] 5
#> [1] 2 3 4 5 6 7 8 9 10 11
CodePudding user response:
I think that what you need are classic nullary functions. They basically just give a name to chunk of code in order to execute it later:
## define function
my_code <- function() {
df <- data.frame(x = 1:10)
print(5)
df$x 1
}
## show code
body(my_code)
# {
# df <- data.frame(x = 1:10)
# print(5)
# df$x 1
# }
## show output
my_code()
# [1] 5
# [1] 2 3 4 5 6 7 8 9 10 11
If it's important to you that you can execute the code without adding parentheses you can use what is called 'active binding'. I would not recommend it, though.
## Variant with active binding:
makeActiveBinding("my_code", function(){
df <- data.frame(x = 1:10)
print(5)
df$x 1
}, .GlobalEnv)
## show output
my_code
# [1] 5
# [1] 2 3 4 5 6 7 8 9 10 11
CodePudding user response:
You can quote()
your code. To execute use eval()
, to print you can coerce to character and cat()
:
# Quote code
code <- quote(
{
df <- data.frame(x = 1:10)
print(5)
df$x 1
}
)
# Execute code
eval(code)
#> [1] 5
#> [1] 2 3 4 5 6 7 8 9 10 11
# Print code
code |>
as.character() |>
(`[`)(-1) |>
paste(collapse = "\n") |>
cat()
#> df <- data.frame(x = 1:10)
#> print(5)
#> df$x 1
Created on 2022-07-31 by the reprex package (v2.0.1)