Movatterモバイル変換


[0]ホーム

URL:


Quick start guide

potions is a package for easily storing and retrievinginformation viaoptions(). It therefore providesfunctionality somewhat similar to{settings},but with syntax based more closely on{here}.The intended use ofpotions is for adding novel informationtooptions() for use within single packages orworkflows.

Basic usage

potions has three basic functions:

The first step is to store data usingbrew(), whichaccepts data in three formats:

Information stored usingbrew can be retrieved usingpour:

library(potions)brew(x =1)paste0("The value of x is ",pour("x"))#> [1] "The value of x is 1"drain()

Interactions with global options

Becausepotions uses a novelS3 object forall data storage, itnever overwrites existing globaloptions, and is therefore safe to use without affectingexisting workflows. For example,print.default takes it’sdefaultdigits argument fromgetOption("digits"):

options("digits")# set to 7 by default#> $digits#> [1] 7print(pi)#> [1] 3.141593

If we usepotions to setdigits, we do notaffect this behaviour. Instead, the user must specifically retrieve datausingpour for these settings to be applied:

library(potions)brew(digits =3)print(pi,digits =pour("digits"))# using potions#> [1] 3.14print(pi)# default is unaffected#> [1] 3.141593

This feature - i.e. storing data in a novelS3 object -means thatpotions can distinguish between interactive usein the console versus being called within a package. Data can beprovided and used independently by multiple packages, and in theconsole, without generating conflicts.

Options stored usingpotions are not persistent acrosssessions; you will need to reload options each time you open a newworkspace. It is unlikely, therefore, that you will need to ‘clear’ thedata stored bypotions at any point. If you do need toremove data, you can do so usingdrain() (without anyfurther arguments).

Usingconfig files

Often it is necessary to share a script, but without sharing certainsensitive information necessary to run the code. A common example is APIkeys or other sensitive information required to download data from a webservice. In such cases, the default, interactive method of usingbrew() is insufficient, i.e.

# start of scriptbrew(list("my-secret-key"="123456"))# shares secret information

To avoid this problem, you can instead supply the path to a filecontaining that information, i.e.

brew(file ="config.yml")# hides secret information

You can then simply add the corresponding file name to yourgitignore, and your script will still run, without sharingsensitive information.

Usingpotions in package development

When weighing up architectural decisions about how packages shouldshare information between functions, there are a few solutions thatdevelopers can choose between:

To usepotions in a package development situation,create a file in theR directory calledonLoad.R, containing the following code:

.onLoad<-function(libname, pkgname) {if(pkgname=="packagenamehere") {    potions::brew(.pkg ="packagenamehere")  }}

This is important because it tellspotions that you aredeveloping a package, what that package is called, and where futurecalls tobrew() from within that package should place theirdata. It is also possible to add defaults here, e.g.

.onLoad<-function(libname, pkgname) {if(pkgname=="packagenamehere") {    potions::brew(      n_attempts==5,      verbose==TRUE,.pkg ="packagenamehere")  }}

Often when developing a package, you will want users to call your ownconfiguration function, rather than callbrew() directly.This provides greater control over the names & types of data storedbypotions, which in turn gives you - the developer -greater certainty when calling those datawithin your packageviapour(). For example, you might want to specify that aspecific argument is supplied as numeric:

packagename_config<-function(fontsize =10){if(!is.numeric(fontsize)){    rlang::abort("Argument `fontsize` must be a number")  }brew(list(fontsize = fontsize))}

An additional benefit of writing a wrapper function is to allow usersto provide their ownconfig file. The easiest way to dothis is to support afile argument within your ownfunction, then pass this directly tobrew():

packagename_config<-function(file =NULL){if(!is.null(file)){brew(file = file)  }}

This approach is risky, however, as it doesn’t allow any checks. Analternative is to intercept the file, run your own checks, then pass theresult tobrew():

packagename_config<-function(file =NULL){if(!is.null(file)){    config_data<- potions::read_config(x)# add any checks to `data` that are needed hereif(length(names(data))!=length(data)){      rlang::abort("Not all entries are named!")    }# pass to `brew`brew(config_data)  }}

[8]ページ先頭

©2009-2025 Movatter.jp