{scribe} 0.3.0 release

A package to support Rscript files

R
{scribe}
Published

October 21, 2023

After months of using my own Rscript utils with {scribe} I’ve failed to notice a now obvious error in my attempts to include type conversions. The original approach was a little too complicated and a too much for what would be needed in most cases.

This update includes a breaking change for how conversion works in {scribe}.

In the prior minor release, this would be valid:

Code
library(scribe)
ca <- command_args(string = "-a 1 -b 0")
ca$add_argument("-a", convert = integer())
ca$add_argument("-b", convert = character())
args <- ca$parse()
args$a + args$b
#> a
#> [1] 1
#> 
#> $b
#> [1] "0"

However, there were issues with trying to use a default value and trying to use a conversion value. Instead, a new exported scribe_convert() is included to handle default and custom conversions.

Code
scribe_convert()
#> function (x, to = default_convert) 
#> {
#>     if (!is.character(x) || is.null(to)) {
#>         return(x)
#>     }
#>     if (is.factor(to)) {
#>         return(factor(x, levels = levels(to), ordered = is.ordered(to)))
#>     }
#>     if (is.function(to)) {
#>         to <- match.fun(to)
#>         return(to(x))
#>     }
#>     mode(x) <- mode(to)
#>     storage.mode(x) <- storage.mode(to)
#>     attributes(x) <- attributes(to)
#>     class(x) <- class(to)
#>     x
#> }
#> <bytecode: 0x5579b81e89a0>
#> <environment: namespace:scribe>

This defaults to returning value_convert() (which may be unexported in the future) and provides other options for "none", and "evaluate". The latter provides useful alternatives for including new values:

Code
a <- new_arg(convert = scribe_convert("evaluate"))
a$convert("1:2")
#> [1] 1 2
a$convert("data.frame(a = 1, b = 2)")
#>   a b
#> 1 1 2

You still have the option for custom conversions, and use the methods of scribe_value() by just passing the method as a string.

Code
ca <- command_args(c("-a", 0, "-b", "2023-10-21", "-c", "list(2, 3)", "-d", 4.4, "-e", 5))
ca$add_argument("-a", convert = "none")
ca$add_argument("-b", convert = "default")
ca$add_argument("-c", convert = "evaluate")
ca$add_argument("-d", convert = as.integer)
ca$add_argument("-e", convert = \(x) rep("value", x))
str(ca$parse())
#> List of 5
#>  $ a: chr "0"
#>  $ b: POSIXct[1:1], format: "2023-10-21"
#>  $ c:List of 2
#>   ..$ : num 2
#>   ..$ : num 3
#>  $ d: int 4
#>  $ e: chr [1:5] "value" "value" "value" "value" ...