Re: [Rd] Registering S3 class from external package

From: John Chambers <jmc_at_r-project.org>
Date: Thu 18 Aug 2005 - 21:23:34 GMT

Your description is a bit too vague to be sure, but it sounds as if you're trying to do something that breaks the basic namespace idea.

Paul Roebuck wrote:

> The package I'm working on can extract data from external
> packages but would otherwise have no dependency on them.
> However, I desire to be able to dispatch based on an
> external S3 class if its package is attached (.First.lib).

Dispatch from where? If you mean from a generic function inside your package's namespace, then the corresponding class definitions need to be defined in or imported into that namespace when it's constructed. One of the main virtues of the namespace mechanism is that the known classes (& therefore the dispatch behavior) are fixed by the package source + its imports. This means that the behavior of the package is insulated against effects from attaching other packages.

OTOH, if you mean dispatch from a generic function in the global environment or another (non-NAMESPACE) package, then you need to ensure that the setOldClass() takes place in the appropriate environment; e.g. if the generic is in the global environment,

   setOldClass(c("foo", "bar"), where = .GlobalEnv) If you're dispatching from a generic in "somepkg", the setOldClass call should just be a part of the source for that package. But, again, these will not help if you're dispatching from the mypkg namespace; that's just what the mechanism is trying to avoid.

In case it's not clear, the setOldClass() call defines a special kind of   S4 class for each of the S3 classes. Therefore it's subject to the same locking rules as setClass() or any other call that needs to do an assignment as a side effect.

> My code is S4-based and its package has NAMESPACE.
>
> Registering the external class prior to the other
> package being attached doesn't seem to work so I am
> attempting to perform the registration once the other
> package has done so. But my namespace is locked by the
> time this occurs. Can someone either tell me how to do
> this, suggest a better alternative, or point me to
> another package that does something similar?
>
> Current attempt is something like the following:
>
> setHook(packageEvent("somepkg", "attach"),
> function(...) {
> cat("* Register", sQuote("oldstyle"),
> "as S3 class", "\n")
> setOldClass(c("oldstyle", "data.frame"),
> where = asNamespace("mypkg"))
> })
>
>
> -----------------
>

>>require(mypkg)

>
> Loading required package: mypkg
> ...
>
>>require(somepkg)

>
> Loading required package: somepkg
> * Register 'oldstyle' as S3 class
> Error in assign(classMetaName(Class), def, where) :
> cannot add bindings to a locked environment
>
>>R.version.string

>
> [1] "R version 2.1.1, 2005-06-20"
>
> ----------------------------------------------------------
> SIGSIG -- signature too long (core dumped)
>
> ______________________________________________
> R-devel@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>
>
> !DSPAM:42fb68c222117714262142!
>

R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel Received on Fri Aug 19 07:26:35 2005

This archive was generated by hypermail 2.1.8 : Mon 24 Oct 2005 - 22:27:39 GMT