implicitGeneric           package:methods           R Documentation

Manage Implicit Versions of Generic Functions

Description:

     Create or access implicit generic functions, used to enforce
     consistent generic versions of functions that are not currently
     generic.  Function 'implicitGeneric()' returns the implicit
     generic version, 'setGenericImplicit()' turns a generic implicit,
     'prohibitGeneric()' prevents your function from being made
     generic, and 'registerImplicitGenerics()' saves a set of implicit
     generic definitions in the cached table of the current session.

Usage:

     implicitGeneric(name, where, generic)
     setGenericImplicit(name, where, restore = TRUE)
     prohibitGeneric(name, where)
     registerImplicitGenerics(what, where)

Arguments:

    name: Character string name of the function.

   where: Package or environment in which to register the implicit
          generics.  When using the functions from the top level of
          your own package source, this argument can usually be omitted
          (and should be).

 generic: Optionally, the generic function definition to be cached, but
          usually omitted.   See Details section.

 restore: Should the non-generic version of the function be restored
          after the current.

    what: For 'registerImplicitGenerics()', Optional table of the
          implicit generics to register, but nearly always omitted.  
          See Details section.

Details:

     Multiple packages may define methods for the same function, using
     the version of a function stored in one package.  All these
     methods should be marshaled and dispatched consistently when a
     user calls the function.  For consistency, the generic version of
     the function must have a unique definition (the same arguments
     allowed in methods signatures, the same values for optional slots
     such as the value class, and the same standard or non-standard
     definition of the function itself).

     If the original function is already an S4 generic, there is no
     problem.  The implicit generic mechanism enforces consistency when
     the version in the package owning the function is _not_ generic. 
     If a call to 'setGeneric()' attempts to turn a function in another
     package into a generic, the mechanism compares the proposed new
     generic function to the implicit generic version of that function.
     If the two agree, all is well. If not, and if the function belongs
     to another package, then the new generic will not be associated
     with that package.  Instead, a warning is issued and a separate
     generic function is created, with its package slot set to the
     current package, not the one that owns the non-generic version of
     the function. The effect is that the new package can still define
     methods for this function, but it will not share the methods in
     other packages, since it is forcing a different definition of the
     generic function.

     The right way to proceed in nearly all cases is to call
     'setGeneric("foo")', giving _only_ the name of the function; this
     will automatically use the implicit generic version. If you don't
     like that version, the best solution is to convince the owner of
     the other package to agree with you and to insert code to define
     the non-default properties of the function (even if the owner does
     not want 'foo()' to be a generic by default).

     For any function, the implicit generic form is a standard generic
     in which all formal arguments, except for '...', are allowed in
     the signature of methods. If that is the suitable generic for a
     function, no action is needed. If not, the best mechanism is to
     set up the generic in the code of the package owning the function,
     and to then call 'setGenericImplicit()' to record the implicit
     generic and restore the non-generic version.  See the example.

     Note that the package can define methods for the implicit generic
     as well; when the implicit generic is made a real generic, those
     methods will be included.

     Other than predefining  methods, the usual reason for having a
     non-default implicit generic is to provide a non-default
     signature, and the usual reason for _that_ is to allow lazy
     evaluation of some arguments.  See the example.  All arguments in
     the signature of a generic function must be evaluated at the time
     the function needs to select a method.  (But those arguments can
     be missing, with or without a default expression being defined;
     you can always examine 'missing(x)' even for arguments in the
     signature.)

     If you want to completely prohibit anyone from turning your
     function into a generic, call 'prohibitGeneric()'.

Value:

     Function 'implicitGeneric()' returns the implicit generic
     definition (and caches that definition the first time if it has to
     construct it).

     The other functions exist for their side effect and return nothing
     useful.

See Also:

     'setGeneric'

Examples:

     ### How we would make the function with() into a generic:

     ## Since the second argument, 'expr' is used literally, we want
     ## with() to only have "data" in the signature.

     ## Note that 'methods'-internal code now has already extended  with()
     ## to do the equivalent of the following
     ## Not run: 
     setGeneric("with", signature = "data")
     ## Now we could predefine methods for "with" if we wanted to.

     ## When ready, we store the generic as implicit, and restore the original
     setGenericImplicit("with")

     ## (This example would only work if we "owned" function with(),
     ##  but it is in base.)## End(Not run)

     implicitGeneric("with")

