Search code examples
rr6

Access formal arguments of an R6 method


Is there a way to access the arguments of an R6 method? For example, I can access the arguments of rstan::stan() with:

library(rstan)
formalArgs(rstan::stan)
#>  [1] "file"            "model_name"      "model_code"      "fit"            
#>  [5] "data"            "pars"            "chains"          "iter"           
#>  [9] "warmup"          "thin"            "init"            "seed"           
#> [13] "algorithm"       "control"         "sample_file"     "diagnostic_file"
#> [17] "save_dso"        "verbose"         "include"         "cores"          
#> [21] "open_progress"   "..."             "boost_lib"       "eigen_lib"

However, the cmdstanr uses R6 classes. So I can see all of the arguments for the $sample() method by looking at the accompanying help page (``?cmdstanr::model-method-sample\``). But I can’t seem to find a way to access the arugments in the same way. For example, this fails:

# remotes::install_github("stan-dev/cmdstanr")
library(cmdstanr)
formalArgs(cmdstanr::`model-method-sample`)
#> Error: 'model-method-sample' is not an exported object from 'namespace:cmdstanr'

Is there a way to access the formal arguments of an R6 method?

Created on 2021-11-22 by the reprex package (v2.0.1)


Solution

  • A basic feature of R6 is that methods belong to objects. They are not bound in the package namespace, per se, so it is not surprising that you are not able to access them with :: or :::. Here is an example taken directly from ?R6::R6Class:

    ## An "R6ClassGenerator" object defining an R6 class
    Queue <- R6::R6Class("Queue",
      public = list(
        initialize = function(...) {
          for (item in list(...)) {
            self$add(item)
          }
        },
        add = function(x) {
          private$queue <- c(private$queue, list(x))
          invisible(self)
        },
        remove = function() {
          if (private$length() == 0) return(NULL)
          # Can use private$queue for explicit access
          head <- private$queue[[1]]
          private$queue <- private$queue[-1]
          head
        }
      ),
      private = list(
        queue = list(),
        length = function() base::length(private$queue)
      )
    )
    
    ## A "Queue" object defining an R6 class instance
    q <- Queue$new(5, 6, "foo")
    

    You can access public methods from the "R6ClassGenerator" object or the "Queue" object as follows:

    a1 <- Queue$public_methods$add
    a2 <- q$add
    identical(a1, a2, ignore.environment = TRUE) # TRUE
    

    Passing either a1 or a2 to formalArgs gets the names of the formal arguments.

    a1
    # function(x) {
    #                      private$queue <- c(private$queue, list(x))
    #                      invisible(self)
    #                    }
    
    formalArgs(a1)
    # [1] "x"
    

    The R6 class internal to cmdstanr is "CmdStanModel", and $sample() is a public method of that class, so you can access the names of the formal arguments of $sample() with

    formalArgs(cmdstanr:::CmdStanModel$public_methods$sample)
    #  [1] "data"                   "seed"                  
    #  [3] "refresh"                "init"                  
    #  [5] "save_latent_dynamics"   "output_dir"            
    #  [7] "output_basename"        "sig_figs"              
    #  [9] "chains"                 "parallel_chains"       
    # [11] "chain_ids"              "threads_per_chain"     
    # [13] "opencl_ids"             "iter_warmup"           
    # [15] "iter_sampling"          "save_warmup"           
    # [17] "thin"                   "max_treedepth"         
    # [19] "adapt_engaged"          "adapt_delta"           
    # [21] "step_size"              "metric"                
    # [23] "metric_file"            "inv_metric"            
    # [25] "init_buffer"            "term_buffer"           
    # [27] "window"                 "fixed_param"           
    # [29] "validate_csv"           "show_messages"         
    # [31] "cores"                  "num_cores"             
    # [33] "num_chains"             "num_warmup"            
    # [35] "num_samples"            "save_extra_diagnostics"
    # [37] "max_depth"              "stepsize"