From jmc at R-project.org  Thu Aug 18 23:23:34 2005
From: jmc at R-project.org (John Chambers)
Date: Thu, 18 Aug 2005 17:23:34 -0400
Subject: [Rd] Registering S3 class from external package
In-Reply-To: <Pine.OSF.4.58.0508110835330.193766@odin.mdacc.tmc.edu>
References: <Pine.OSF.4.58.0508110835330.193766@odin.mdacc.tmc.edu>
Message-ID: <4304FC56.9060006@R-project.org>

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 at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
> 
> 
> !DSPAM:42fb68c222117714262142!
>



[Rd] Registering S3 class from external package
John Chambers