standardGeneric("foo")
By definition, coercing the classes means that the actual argument, when the method is evaluated, has the class specified in the chosen method's signature, not necessarily its original class. This is essential in an object-based system, because the writer of the method needs to know that it's dealing with a known class (and extensions can involve coerce methods, so the actual argument may not look anything like the selected class). The partial exception is that virtual classes in the signature always expect the actual object to have some non-virtual class.
If you've used other object-oriented languages such as Java or C++, this may seem odd or restrictive, but it is part of the essential evaluation model for S. You don't need to be restricted by it, however, if you have an example where it really doesn't fit what you want to do. The S evaluator is available directly, so you can program a different method dispatch mechanism. These notes describe how.
foo = function(x, y) { eval(selectMethod()) }(This relies on an extension to the selectMethod function post-dating the book, in which it uses the actual arguments to define the method selection.)
The methods for virtual dispatch must be specially designed. As mentioned before, they can't in general assume anything about the actual form (slots, for example) in the arguments. They can assume that the arguments extend the class for which the method was written. I imagine most such methods would extract some general information about the object (its class, for example), and then call the as function to coerce the argument to a known form.
dput = function(x = NULL, file = stdout()) { sig = selectMethodSignature("dput", class(x)) if(identical(sig, class(x))) standardGeneric("dput") else eval(functionBody(selectMethod("dput", character()))) invisible(x) }
if(missing(x)) "missing" else class(x)