1

I am using a function factory defined by someone else and I cannot change it. It is common to need to generate several functions with this factory at the beginning of every run. In my attempt at a toy example, it's as if I need many such power_ functions frequently. Currently as a user of otherpackage, I must include lines like power2 <- power_factory(2) in my scripts.

otherpackage::power_factory <- function(exp) {
  function(x) {
    x ^ exp
  }
}

power2 <- power_factory(2)
power3 <- power_factory(3)

I would like to avoid these lines by writing my own package, so I can instead use mypackage::power2() in my scripts. Normally, if I wanted to wrap these functions in a package, I could just use the factory to build them inside the package. However, this factory depends on some outside input, here credential, that I cannot write inside my package. This makes the factory error if I put power2 <- power_factory(2) inside the package:

# credential <- "my_secret"
otherpackage::power_factory <- function(exp) {
  print(credential)
  function(x) {
    x ^ exp
  }
}

power2 <- power_factory(2)
#> Error in print(credential): object 'credential' not found

Created on 2019-03-07 by the reprex package (v0.2.1)

Is there a way around this problem? The end goal, as above, is to be able to call mypackage::power2() instead of needing to do power2 <- power_factory(2) and many variations on such at the start of each script.

Calum You
  • 14,687
  • 4
  • 23
  • 42
  • When you load `mypackage`, the namespace is typically locked once loaded, so the user later wanting to define `power2` does not necessarily work. There are cheats around this, but I have yet to hear somebody recommend solid rationale why this should be allowed and easy. Is there a reason you cannot make it an argument of the factory, as in `power_factory(2, credential)`? – r2evans Mar 08 '19 at 00:38
  • The reason is that I cannot edit `power_factory` since it comes from a different, non-public package (and I can't speak to the reasons for the author choosing to make the interface like this). I am not sure what you mean by the "user later wanting to define `power2`", I'll add some clarifying text – Calum You Mar 08 '19 at 00:41
  • 2
    Where and when is `credential` defined? You can write your own function factory as a wrapper around the other factory, thereby safe-guarding acquisition of the credential, such as `myfactory <- function(...) { credential <- get_credential(); otherpackage::power_factor(...); }` – r2evans Mar 08 '19 at 02:25
  • You can achieve this by creating an environment `env` with the credential and then setting the `power_factor` function environment to `env`. See the McFlick's answer here: https://stackoverflow.com/questions/12279076/r-specify-function-environment. In particular the helper function `with_env` – dipetkov Mar 08 '19 at 02:56
  • I was able to get the wrapper working r2evans, will accept if you submit as answer – Calum You Mar 14 '19 at 20:57

0 Answers0