Reputation: 835
How can I reliably tell if formal function arguments have a default value from outside the function?
In the below example, I'd like to ensure that the test below will not fail to find when an argument has or does not have a default value:
myfun <- function(a, b=1, ...) {}
formals(myfun)
for (n in names(formals(myfun))) {
if (is.name(formals(myfun)[[n]])) {
cat(n, "has no default value\n")
} else {
cat(n, "has a default value:", formals(myfun)[[n]], "\n")
}
}
is.name
is the best test that I've come up with, but I'd prefer to see both that it is a name and that it is empty (or better yet a more definitive test like missing
would provide inside the function).
Upvotes: 5
Views: 155
Reputation: 1727
You can do an empty string comparison to test if each value is empty:
myfun <- function(a, b=1, ...) {}
formals(myfun)
for (n in names(formals(myfun))) {
if (formals(myfun)[[n]] == "") {
cat(n, "has no default value\n")
} else {
cat(n, "has a default value:", formals(myfun)[[n]], "\n")
}
}
a has no default value
b has a default value: 1
... has no default value
UPDATED FOR RARE BUT POSSIBLE CASE OF WANTING TO TREAT "" AS DEFINED DEFAULT OF EMPTY STRING:
myfun <- function(a, b=1, c="", ...) {}
formals(myfun)
for (n in names(formals(myfun))) {
if (!nzchar(formals(myfun)[[n]]) & is.name(formals(myfun)[[n]])) {
cat(n, "has no default value\n")
} else {
cat(n, "has a default value:", formals(myfun)[[n]], "\n")
}
}
a has no default value
b has a default value: 1
c has a default value:
... has no default value
EXTRA EDIT FOR SAKE OF COMPLETENESS: To actually display the empty quote characters in the result and define formals(myfun)
instead of calling it over and over:
myfun <- function(a, b=1, c="", ...) {}
myfun_args <- formals(myfun)
for (n in names(myfun_args)) {
if (!nzchar(myfun_args[[n]]) & is.name(myfun_args[[n]])) {
cat(n, "has no default value\n")
} else {
if (!nzchar(myfun_args[[n]]))
cat(n, "has a default value:", dQuote(myfun_args[[n]]), "\n")
else
cat(n, "has a default value:", myfun_args[[n]], "\n")
}
}
a has no default value
b has a default value: 1
c has a default value: “”
... has no default value
Upvotes: 5