Just a note: this technique is called memoisation. Hadley On Wed, Oct 14, 2009 at 3:42 PM, Benilton Carvalho <bcarv...@jhsph.edu> wrote: > Thank you very much, Martin. :) > > b > > On Oct 14, 2009, at 5:23 PM, Martin Morgan wrote: > >> Steve Lianoglou wrote: >>> >>> Very clever, that looks to do the trick! >> >> I think though that all Square's then share the same environment >> (created in the prototype) and hence area. >> >>> area(new("Square", length=50, width=100)) >> >> Accessing >> [1] 50 >> >> >> Which is quite efficient at doing the calculation, but maybe not what is >> expected... >> >> The solution is to create the area environment in an 'initialize' method. >> >> A different approach, but along similar lines, might make 'area' a >> function that exploits lexical scope. Here's an area 'factory' >> >> areaf <- function() { >> area <- NULL >> function(x) { >> if (is.null(area)) { >> message("expensive") >> area <<- x...@length * x...@width >> } >> area >> } >> } >> >> that we use in the initialize method >> >> setMethod(initialize, "Rect", >> function(.Object, ..., length=.obj...@length, >> width=.obj...@width) >> { >> callNextMethod(.Object, area=areaf(), length=length, >> width=width, ...) >> }) >> >> setMethod(area, "Rect", function(x) x...@area(x)) >> >> The signature of initialize is such that one could >> >> setReplaceMethod("length", c("Rect", "numeric"), function(x, value) { >> initialize(x, length=value) >> }) >> >> >> so >> >>> a <- new("Rect", length=10, width=5) >>> area(a) >> >> expensive >> [1] 50 >>> >>> area(a) # cheap >> >> [1] 50 >>> >>> b <- a >>> area(b) >> >> [1] 50 >>> >>> length(b) <- 20 >>> area(a) >> >> [1] 50 >>> >>> area(b) >> >> expensive >> [1] 100 >> >> Martin >> >>> >>> Thanks, >>> >>> -steve >>> >>> On Oct 14, 2009, at 2:57 PM, Benilton Carvalho wrote: >>> >>>> If you change 'area' to an environment, you may be able to get >>>> something close to what you want. >>>> >>>> For example: >>>> >>>> setClass("Square", >>>> representation( >>>> length='numeric', >>>> width='numeric', >>>> area='environment' >>>> ), >>>> prototype( >>>> length=0, >>>> width=0, >>>> area=new.env() >>>> ) >>>> ) >>>> >>>> setGeneric("area", function(x) standardGeneric("area")) >>>> setMethod("area", "Square", >>>> function(x){ >>>> if (length(ls(x...@area)) == 0){ >>>> message("Computing") >>>> assign("area", x...@width * x...@length, envi...@area) >>>> } >>>> message("Accessing") >>>> get("area", envi...@area) >>>> }) >>>> >>>> tmp <- new("Square", length=5, width=10) >>>> area(tmp) ## This should show "computing" and "accessing" >>>> area(tmp) ## the 2nd call should show 'accessing' only >>>> >>>> >>>> b >>>> >>>> >>>> >>>> On Oct 14, 2009, at 3:31 PM, Steve Lianoglou wrote: >>>> >>>>> Hi, >>>>> >>>>> I was wondering if there was a way to store the results of a >>>>> computationally expensive "getter" call on an S4 object, so that it is >>>>> only calculated once for each object. >>>>> >>>>> Trivial example: let's say I want to cache the "expensive" area >>>>> calculation of a square object. >>>>> >>>>> setClass("Square", >>>>> representation( >>>>> length='numeric', >>>>> width='numeric', >>>>> area='numeric' >>>>> ), >>>>> prototype( >>>>> length=0, >>>>> width=0, >>>>> area=-1 >>>>> ) >>>>> ) >>>>> >>>>> setGeneric("area", function(x) standardGeneric("area")) >>>>> setMethod("area", "Square", >>>>> function(x) { >>>>> if (x...@area == -1) { >>>>> �...@area <- x...@width * x...@height >>>>> } >>>>> x...@area >>>>> }) >>>>> >>>>> Now the first time I call ``area(my.square)`` it computes >>>>> ``my.squ...@width * my.squ...@height``, but each subsequent call >>>>> returns `...@area`` since the area computation has already been calc'd >>>>> and set for this object. >>>>> >>>>> Is this possible? I'm guessing the R pass by value semantics is going >>>>> to make this one difficult ... is there some S4 reference I missed >>>>> that has this type of info from? >>>>> >>>>> Thanks, >>>>> -steve >>>>> >>>>> -- >>>>> Steve Lianoglou >>>>> Graduate Student: Computational Systems Biology >>>>> | Memorial Sloan-Kettering Cancer Center >>>>> | Weill Medical College of Cornell University >>>>> Contact Info: http://cbio.mskcc.org/~lianos/contact >>>>> >>>>> ______________________________________________ >>>>> R-help@r-project.org mailing list >>>>> https://stat.ethz.ch/mailman/listinfo/r-help >>>>> PLEASE do read the posting guide >>>>> http://www.R-project.org/posting-guide.html >>>>> and provide commented, minimal, self-contained, reproducible code. >>>> >>> >>> -- >>> Steve Lianoglou >>> Graduate Student: Computational Systems Biology >>> | Memorial Sloan-Kettering Cancer Center >>> | Weill Medical College of Cornell University >>> Contact Info: http://cbio.mskcc.org/~lianos/contact >>> >>> ______________________________________________ >>> R-help@r-project.org mailing list >>> https://stat.ethz.ch/mailman/listinfo/r-help >>> PLEASE do read the posting guide >>> http://www.R-project.org/posting-guide.html >>> and provide commented, minimal, self-contained, reproducible code. >> >> >> -- >> Martin Morgan >> Computational Biology / Fred Hutchinson Cancer Research Center >> 1100 Fairview Ave. N. >> PO Box 19024 Seattle, WA 98109 >> >> Location: Arnold Building M1 B861 >> Phone: (206) 667-2793 > > ______________________________________________ > R-help@r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >
-- http://had.co.nz/ ______________________________________________ R-help@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code.