Add objects to package namespace
Asked Answered
H

3

40

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 ?

Hypnotic answered 22/6, 2010 at 14:40 Comment(0)
D
43

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

environment(myfun) <- asNamespace('stats')
Declassify answered 4/8, 2010 at 2:25 Comment(2)
in case that you need to modify an existing package function, which is to be called by other package functions, here is the solutionHighstrung
How do you check whether this has worked successfully?Estivation
A
23

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")
Aracelyaraceous answered 22/6, 2010 at 21:43 Comment(2)
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).Hypnotic
I'm late to the party, but this may be useful for others: The namespace actually is an environment. namespace:stats is a descendent the global environment and contains all the objects. The exported objects get copied over to package:stats, which is an ancestor of the global environment.Intercourse
B
7

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.

Bourges answered 22/6, 2010 at 14:46 Comment(2)
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.Hypnotic
@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.Bourges

© 2022 - 2024 — McMap. All rights reserved.