Skip to content

proto: make a parameter persist

6 messages · Ben quant, Gabor Grothendieck

#
On Sat, Feb 18, 2012 at 12:44 AM, Ben quant <ccquant at gmail.com> wrote:
This is not very different from what you have already but here it is
for comparison.  Note that the with(...) line has the same meaning as
.$x <- .$x + .$x2 :

oo <- proto(
   x = c(10, 20, 15, 19, 17),
   x2 = 5,
   bias = function(., x2) {
      if (!missing(x2)) .$x2 <- x2
      with(., x <- x + x2)
   }
)
2 days later
#
On Tue, Feb 21, 2012 at 12:15 AM, Ben quant <ccquant at gmail.com> wrote:
There are multiple issues here:

1. The expr is executed at the time you define the proto object -- its
not a method.  Once the proto object is defined the only thing that is
left is the result of the computation so you can't spawn a child and
then figure that this code will be rerun as if its a constructor.  You
need to define a constructor method to do that.

2. You can't use dot as if it were a special notation -- its not.  A
single dot is just the name of an ordinary variable and is not
anything special that proto knows about.  In the examples where dot is
used its used as the first formal argument to various methods but this
was the choice of the method writer and not something required by
proto.  We could have used self or this or any variable name.

3. Note that the code in expr=... is already evaluated in the
environment of the proto object so you don't need with.

4. I personally find it clearer to reserve = for argument assignment
and use <- for ordinary assignment but that is mostly a style issue
and its up to you:

5. The discussion of traits in the proto vignette illustrates
constructors -- be sure to read that.  Traits are not a special
construct built into proto but rather its just a way in which you can
use proto.   That is one of the advantages of the prototype model of
OO -- you don't need to have special language constructs for many
situations where ordinary OO needs such constructs since they are all
subsumed under one more general set of primitives.

Here we define the trait MakeProto (again, traits are not a special
language feature of proto but are just a way of using it):

MakeProto <- proto(
   new = function(., ...) {
      .$proto(expr = if ( !is.null(d1) ) d3 <- d1 + d2, ...)
   },
   d1 = NULL,
   d2 = 5,
   d3 = NULL
)

oo <- MakeProto$new()
oo$d1 # NULL
oo$d2 # 5
oo$d3 # NULL

oo2 <- MakeProto$new(d1 = 7)
oo2$d1 # 7
oo2$d2 # 5
oo2$d3 # 12

In the above oo$d1, oo$d2, oo$d3 are actually located in MakeProto and
delegated to oo so that when one writes oo$d2 it looks into MakeProto
since it cannot find d2 in oo.  oo2$d2 is also not in oo2 but
delegated from MakeProto; however, oo2$d1 and oo2$d3 are located in
oo2 itself.  That is due to the way we set it up and we could have set
it up differently.  Try str(MakeProto); str(oo); str(oo2) to  see
this.