In my code, I needed to check which package the function is defined from (in my case it was exprs()
: I needed it from Biobase
but it turned out to be overriden by rlang
).
From this SO question, I thought I could use simply environmentName(environment(functionname))
. But for exprs
from Biobase
that expression returned empty string:
environmentName(environment(exprs))
# [1] ""
After checking the structure of environment(exprs)
I noticed that it has .Generic
member which contains package name as an attribute:
environment(exprs)$.Generic
# [1] "exprs"
# attr(,"package")
# [1] "Biobase"
So, for now I made this helper function:
pkgparent <- function(functionObj) {
functionEnv <- environment(functionObj)
envName <- environmentName(functionEnv)
if (envName!="")
return(envName) else
return(attr(functionEnv$.Generic,'package'))
}
It does the job and correctly returns package name for the function if it is loaded, for example:
pkgparent(exprs)
# Error in environment(functionObj) : object 'exprs' not found
library(Biobase)
pkgparent(exprs)
# [1] "Biobase"
library(rlang)
# The following object is masked from ‘package:Biobase’:
# exprs
pkgparent(exprs)
# [1] "rlang"
But I still would like to learn how does it happen that for some packages their functions are defined in "unnamed" environment while others will look like <environment: namespace:packagename>
.