An embedded and charset-unspecified text was scrubbed... Name: not available URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20120217/4dc46fc7/attachment.pl>
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:
The code below works as expected but: Using the proto package, is this the best way to 1) make a parameter persist if the parameter is passed in with a value, 2) allow for calling the bias() function without a parameter assignment, 3) have the x2 value initialize as 5? Thanks for your feedback. Giving the proto package a test beat and establishing some templates for myself.
oo <- proto(expr = {x = c(10, 20, 15, 19, 17) ? ? ? ? ? ? ? ? ? ? x2 = 5 # so x2 initializes as 5, but can be overwritten with param assignment ? ? ? ? ? ? ? ? ? ? bias <- function(.,x2=.$x2) { # x2=.$x2 so no default param is needed ? ? ? ? ? ? ? ? ? ? ? ? .$x2 = x2 # so x2 persists in the env ? ? ? ? ? ? ? ? ? ? ? ? .$x <- .$x + x2 ? ? ? ? ? ? ? ? ? ? } })> o = oo$proto()> o$x # [1] 10 20 15 19 17> o$x2 #[1] 5> o$bias(x2 = 100)> o$x2 # [1] 100> o$x # [1] 110 120 115 119 117
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)
}
)
Statistics & Software Consulting GKX Group, GKX Associates Inc. tel: 1-877-GKX-GROUP email: ggrothendieck at gmail.com
2 days later
An embedded and charset-unspecified text was scrubbed... Name: not available URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20120220/63903870/attachment.pl>
An embedded and charset-unspecified text was scrubbed... Name: not available URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20120220/5c9b1da6/attachment.pl>
On Tue, Feb 21, 2012 at 12:15 AM, Ben quant <ccquant at gmail.com> wrote:
Thanks again for your so far on proto. I have another question.
What is the best way to "do stuff" based on data prior to calling a
function? I tried the code below without expr (and including commas after
data member assignments), but it errors out. I'd like to make decisions
based on inputs during proto object construction and prep my data_members
for use in the functions that (would) follow. I think I could probably get
around this with a small function with other functions within the same proto
object, but I'd rather not repeat that in each function...if that makes
sense. See my last line of code below:
makeProto = proto( expr={
? data_member1=NULL
? data_member2=5
? data_member3=NULL
? if(!is.null(data_member1)){
??? with(.,data_member3 = data_member1 + data_member2)
? }
})
oo = makeProto$proto()
oo$data_member1 # NULL
oo$data_member2 # 5
oo$data_member3 # NULL
oo2 = makeProto$proto(data_member1 = 7)
oo2$data_member1 # 7
oo2$data_member2 # 5
oo2$data_member3 # I want this to be 12 (12 = 7 + 5), but I get NULL
Its late for me so hopefully this makes sense...
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.
Statistics & Software Consulting GKX Group, GKX Associates Inc. tel: 1-877-GKX-GROUP email: ggrothendieck at gmail.com
An embedded and charset-unspecified text was scrubbed... Name: not available URL: <https://stat.ethz.ch/pipermail/r-help/attachments/20120221/14f7a75d/attachment.pl>