-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add import::config() function or similar? #63
Comments
I like that. Package options are often hidden and there is no easy way to explicitly document them. I was afraid that the logic would have to dictate that the parameters would have to default to As an option to manage options, there is package |
Good point, although most of the parameters that I think are appropriate for a config option are just regular variables:
Configuring the object names does not make sense, and I think Good pointer on |
I was working recently on a similar problem and managed to find/implement a set of function to hook into the
These two function hook into the Since Additional helper functions can be:
Now that I am looking at this, perhaps This is essentially a more dynamic version of what Which style do we prefer? |
I'm traveling, but glad to see some interest on this. I'd want to think on this together sometime after I come back (realistically sometime in March). In the meantime, it seems that guidance on how to store internal state such as this has evolved: https://r-pkgs.org/data.html#sec-data-state So my current preference would probably be to stay with one external function such as |
In that case, this is the example implementation mentioned in the article: https://github.com/r-lib/usethis/blob/175bf649163976351d972cedca6017517e087533/R/proj.R I was experimenting with something of that sense (new env to store the state) but chose to hook on the global R options. Now the hard question is: How do we handle interaction between arguments and globally set options? Ideal behaviour is:
This means that instead of In the same way as many graphical options can be specified, but are typically documented only in Alternatively, if we have getter that the user can use in addition the the setter
This is the same method used occasionally with
It also means that the functions themselves do not need any magical mechanism to decide on the default value and everything is quite visible in function annotation, well except for the default value itself. |
Yes, the global options were my first though as well. It was your comment about potential naming conflicts in a flat uncontrolled namespace (options starting with
Agreed,
Yes, setting default to an analogue of And on inspection, it seems like it might not need to be too complex or magical. I tried a small proof of concept using just the <- new.env(parent = emptyenv())
f <- function(x = "default") {
if (missing(x) && exists("x", the)) {
x <- the$x
}
x
}
# Value passed as parameter
f("parameter")
#> [1] "parameter"
# No value passed, no config, use global default
f()
#> [1] "default"
# No value passed, but value set in config
the$x <- "config"
f()
#> [1] "config" It's a line or three for each parameter that can be |
When I see The This would make it less obvious what the default parameters are, but more obvious how they are evaluated in the first place and thus how to reason about them. Alternatively edit: For the |
Apologies for the radio silence recently. I've given this some thought and my view is that we should strive to maintain backwards compatibility in function signatures (as a special case of the importance of maintaining backwards compatibility overall), unless there is a very compelling reason not to. I appreciate that overloading the default parameters without explicit I'd be happy to work on integrating an If @smbache has other ideas about what would be the best approach for configuring |
As the number of dot-prefixed parameters to
import::from()
has increased considerably, I have been thinking that animport::config()
function might be a good addition to the package. The formals (the declared function signature) ofimport::from()
would not be changed, but anymissing()
parameters would be overridden by options set with something like:The option values themselves could be stored using
base::options
, but the rationale for having a separate function is that both findability and the ability to perform sanity checking on the parameter values would be improved.Thoughts?
The text was updated successfully, but these errors were encountered: