another S4 question ...

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

another S4 question ...

Ben Bolker-2

  The default generic method for "show" has arguments
show(object) -- (no "...")   -- which precludes any kind
of arguments like "digits", etc.

  Is it impossible, or a horrible idea, to override the
generic definition?  (The "arm" package has defined a
new generic, "display", which does a similar thing but
has an intermediate level of detail (between "print/show"
and "summary")

  Ben Bolker



______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

signature.asc (260 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: another S4 question ...

Martin Morgan
Ben --

My vote would be against overriding the generic for show. If for some
reason your version proves inadequate, you force the user to
(conditional on loading your package) disambiguate 'show' to get the
methods package behavior.

?show says in part

     Formal methods for 'show' will usually be invoked for automatic
     printing (see the details).

and it's difficult to provide ... with automatic printing. On the
other hand, the naive user is probably expecting to be able to print()
your object (much as they are expecting to use 'as' rather than
'coerce'). ?show goes on to say

     The 'methods' package overrides the base definition of
     'print.default' to arrange for automatic printing to honor methods
     for the function 'show'.  This does not quite manage to override
     old-style printing methods, since the automatic printing in the
     evaluator will look first for the old-style method.

and the following might be a different solution

> setClass("A", representation=representation(x="numeric"))
[1] "A"
> print.A <- function(x, ...) cat("an A\n")
> print(new("A"))
an A

Another solution might be

> rm(print.A)
> setMethod("print", "A", function(x, ...) cat("another A\n"))
Creating a new generic function for "print" in ".GlobalEnv"
[1] "print"
> print(new("A"))
another A

This creates a 'print' generic with an identical signature to 'print',
which might be marginally better than creating another generic (for
'show') with a different signature. I think I'd still go with the
S3-style print, even though it mixes object systems, because it seems
to have the least potential to interfere with other packages.

Martin


Ben Bolker <[hidden email]> writes:

>   The default generic method for "show" has arguments
> show(object) -- (no "...")   -- which precludes any kind
> of arguments like "digits", etc.
>
>   Is it impossible, or a horrible idea, to override the
> generic definition?  (The "arm" package has defined a
> new generic, "display", which does a similar thing but
> has an intermediate level of detail (between "print/show"
> and "summary")
>
>   Ben Bolker
>
>
>
> ______________________________________________
> [hidden email] mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel

--
Martin Morgan
Computational Biology / Fred Hutchinson Cancer Research Center
1100 Fairview Ave. N.
PO Box 19024 Seattle, WA 98109

Location: Arnold Building M2 B169
Phone: (206) 667-2793

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel
Reply | Threaded
Open this post in threaded view
|

Re: another S4 question ...

Ben Bolker-2
  Agreed.  It turns out a similar hack is done in the lme4
package for printMer ...

Martin Morgan wrote:

> Ben --
>
> My vote would be against overriding the generic for show. If for some
> reason your version proves inadequate, you force the user to
> (conditional on loading your package) disambiguate 'show' to get the
> methods package behavior.
>
> ?show says in part
>
>      Formal methods for 'show' will usually be invoked for automatic
>      printing (see the details).
>
> and it's difficult to provide ... with automatic printing. On the
> other hand, the naive user is probably expecting to be able to print()
> your object (much as they are expecting to use 'as' rather than
> 'coerce'). ?show goes on to say
>
>      The 'methods' package overrides the base definition of
>      'print.default' to arrange for automatic printing to honor methods
>      for the function 'show'.  This does not quite manage to override
>      old-style printing methods, since the automatic printing in the
>      evaluator will look first for the old-style method.
>
> and the following might be a different solution
>
>> setClass("A", representation=representation(x="numeric"))
> [1] "A"
>> print.A <- function(x, ...) cat("an A\n")
>> print(new("A"))
> an A
>
> Another solution might be
>
>> rm(print.A)
>> setMethod("print", "A", function(x, ...) cat("another A\n"))
> Creating a new generic function for "print" in ".GlobalEnv"
> [1] "print"
>> print(new("A"))
> another A
>
> This creates a 'print' generic with an identical signature to 'print',
> which might be marginally better than creating another generic (for
> 'show') with a different signature. I think I'd still go with the
> S3-style print, even though it mixes object systems, because it seems
> to have the least potential to interfere with other packages.
>
> Martin
>
>
> Ben Bolker <[hidden email]> writes:
>
>>   The default generic method for "show" has arguments
>> show(object) -- (no "...")   -- which precludes any kind
>> of arguments like "digits", etc.
>>
>>   Is it impossible, or a horrible idea, to override the
>> generic definition?  (The "arm" package has defined a
>> new generic, "display", which does a similar thing but
>> has an intermediate level of detail (between "print/show"
>> and "summary")
>>
>>   Ben Bolker
>>
>>
>>
>> ______________________________________________
>> [hidden email] mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>


______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

signature.asc (260 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: another S4 question ...

Prof Brian Ripley
In reply to this post by Ben Bolker-2
Here is my current understanding: this area has changed a bit recently.

S4 generics of the same name in different packages are regarded as
different.  If you define a generic show() in your package, it will not
have any of the methods defined on methods::show, and likely mask the
latter. So users will be asking 'where have all my show() methods gone?'.

Then there are the perennial scoping problems.  If both your package and
methods have generics for show(), which is found depends on where you are
looking from: you cannot in general 'override' an existing function in
R's scoping system.  For example, any function in another package that
imports 'methods' will find methods:::show and not your version.

This is a generic problem: e.g. both packages stats4 and lme4 have
generics for BIC, and you will get the methods for one or the other
depending on which is found first in the current scope.

On Mon, 10 Dec 2007, Ben Bolker wrote:

>  The default generic method for "show" has arguments
> show(object) -- (no "...")   -- which precludes any kind
> of arguments like "digits", etc.

You can define methods on print(), if you want those arguments.

>  Is it impossible, or a horrible idea, to override the
> generic definition?  (The "arm" package has defined a
> new generic, "display", which does a similar thing but
> has an intermediate level of detail (between "print/show"
> and "summary")
>
>  Ben Bolker
>
>
>

--
Brian D. Ripley,                  [hidden email]
Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
University of Oxford,             Tel:  +44 1865 272861 (self)
1 South Parks Road,                     +44 1865 272866 (PA)
Oxford OX1 3TG, UK                Fax:  +44 1865 272595

______________________________________________
[hidden email] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel