tags:

views:

49

answers:

3

I'd like to push a function inside a package namespace so it can access internal objects of that package (let's use stats package as an example). I've tried using

myfun <- function(x) print(x)
env = loadNamespace("stats")
assign("myfun", myfun , env)

But it is locked. So I've tried to unlock my object

unlockBinding("myfun", env)

Since myfun doesn't exist yet, I can't unlock it.

Any help ?

+3  A: 

You can access internal objects of a package using the triple colon operator :::. Take a look at, for example, as.roman and utils:::.roman2numeric. (Compare this to utils::.roman2numeric.) This could help you avoid having to put your function inside the namespace.

You might also want to look at dont.lockBindings in the mvbutils package, which stops namespaces being locked.

Richie Cotton
If I understand correctly, I cannot unlock a package's Namespace once it is locked (except by reloading it with dont.lockBindings). So it's impossible to add a new function a posteriori.
Etiennebr
@Etiennebr: AFAIK you are correct. Once the namespace is locked, you can't add to it. I still think that `:::` is the way to proceed.
Richie Cotton
+1  A: 

Why not just set the environment of your new function to the right place?

myfun <- function(x) print(x)
environment(myfun) <- as.environment("package:stats")
hadley
I didn't know that ! But I think I would like it to be namespace:stats instead of package:stats. Is there way to do that (just changing it in as.environment() doesn't work).
Etiennebr
The namespace isn't an environment...
hadley
A: 

Along the line of Hadley's solution, but using the environment of the namespace, how about:

environment( myfun) <- asNamespace( 'stats')

Mark Bravington