Skip to main content

ENV_METHOD_HELPER

Constant ENV_METHOD_HELPER 

Source
const ENV_METHOD_HELPER: &str = r#"# Internal helper: bind an environment class's methods to one receiver.
# The class's `$` / `[[` methods handle fields before calling this lookup.
.miniextendr_env_method <- function(self, name, methods) {
  obj <- methods[[name]]
  if (is.environment(obj)) {
    bound <- new.env(parent = emptyenv())
    for (method_name in names(obj)) {
      method <- obj[[method_name]]
      if (is.function(method)) {
        if (isTRUE(attr(method, ".__mx_instance__"))) {
          local({
            m <- method
            bound[[method_name]] <<- function(...) m(self, ...)
          })
        } else {
          bound[[method_name]] <- method
        }
      }
    }
    bound
  } else if (is.null(obj)) {
    matches <- list()
    for (ns_name in names(methods)) {
      ns <- methods[[ns_name]]
      if (is.environment(ns) && exists(name, envir = ns, inherits = FALSE)) {
        method <- ns[[name]]
        if (is.function(method)) matches[[ns_name]] <- method
      }
    }
    if (!length(matches)) return(NULL)
    if (length(matches) > 1L) {
      traits <- sort(names(matches))
      stop(errorCondition(
        sprintf("Method '%s' is provided by multiple traits (%s). Use obj$Trait to select a trait explicitly.", name, paste(traits, collapse = ", ")),
        class = "miniextendr_ambiguous_method", method = name, traits = traits,
        call = .miniextendr_frame_call(parent.frame())
      ))
    }
    m <- matches[[1L]]
    if (isTRUE(attr(m, ".__mx_instance__"))) {
      s <- self
      function(...) m(s, ...)
    } else {
      m
    }
  } else {
    environment(obj) <- list2env(list(.mx_self = self), parent = environment(obj))
    obj
  }
}
"#;
Expand description

Shared method lookup for environment classes. Each returned closure gets its own receiver-binding frame. An inherent method keeps its original enclosure behind that frame, so native symbols and author-supplied R code never resolve through the lookup helper’s locals (#1677). Field lookup and its condition call stay in the S3 method. Flat trait lookup must find a unique method; inherent methods and explicit trait namespaces take priority.