The proto class is an S3 subclass of the R environment
class. In particular this implies that proto objects have single
inheritance and mutable state as all environments do. The proto
function creates and modifies objects of the proto class. It (1)
sets the parent of codeenvir to parent, (2) evaluates expr in
the envir environment and (3) lazily evaluates the arguments in
...{} in the parent environment resetting the environment of any
functions (where the resetting is also done lazily). All such functions are
known as methods and should have the receiver object as their first
argument. Conventionally this is . (i.e. a dot). Also .that
and .super variables are added to the environment envir.
These point to the object itself and its parent, respectively. Note that
proto can be used as a method and overridden like any other method.
This allows objects to have object-specific versions of proto. There
also exist that() and super() functions which have the same
purpose as .that and .super but do not rely on the
.that and .super. .that, .super, that()
and super() can only be used within methods that have their object as
their environment. In addition that() and super() may only be
used within the top level of such methods ( and not within functions within
such methods).as.proto is a generic with methods for environments, proto objects
and lists.
as.proto.list copies each component, el, of the list x
into the the environment or proto object envir for which
FUN(el) is TRUE. Components whose name begins with a dot,
., are not copied unless all.names is TRUE (and
FUN(el) is TRUE). The result is a proto object whose parent is
parent. If envir is omitted a new object is created through a
call to proto with parent and ...{} as arguments. If
parent is also omitted then the current environment is the parent.
Note that if parent is a proto object with its own proto
method then the proto method of the parent will override the one
described here in which case the functionality may differ.
$ can be used to access or set variables and methods in an object.
When $ is used for getting variables and methods, calls of the form
obj$v search for v in obj and if not found search upwards
through the ancestors of obj until found unless the name v
begins with two dots ... In that case no upward search is done.
If meth is a function then obj$meth is an object of class
c("instantiatedProtoMethod", "function") which is a proto
method with the first, i.e. proto slot, already filled in. It is normally
used in the context of a call to a method, e.g. obj$meth(x,y). There
also exists print.instantiatedProtoMethod for printing such objects.
Be aware that an instantiated proto method is not the same as a proto
method. An instantiated proto method has its first argument filled (with
the receiver object) whereas the first argument of a proto method does not.
If it is desired to actually return the method as a value not in the context
of a call then use the form obj$with(meth) or obj[[meth]]
which are similar to with(obj, meth) except that the variation using
with will search through ancestors while [[ will not search
through ancestors). The difference between obj$meth and
obj$with(meth) is that in the first case obj implicitly
provides the first argument to the call so that obj$meth(x,y) and
obj$with(meth)(obj,x,y) are equivalent while in the case of
obj$with(meth) the first argument is not automatically inserted.
$.proto also has a multiple argument form. If three or more
arguments are present then they specify the arguments at which the
instantiated method is to be evaluated. In this form the receiver object
must be specified explicitly. This form can be used in situations where the
highest speed is required such as in the inner loops of computations.
The forms .that$meth and .super$meth are special and should
only be used within methods. .that refers to the object in which the
current method is located and .super refers to the parent of
.that. In both cases the receiver object must be specified as the
first argument -- the receiver is not automatically inserted as with other
usages of $.
$ can be used to set variables and methods in an object. No ancestors
are searched for the set form of $. If the variable is the special
variable .super then not only is the variable set but the object's
parent is set to .super.
A with method is available for proto objects.
is.proto(p) returns TRUE if p is a prototype object.
str.proto is provided for inspecting proto objects.