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) {
  x...@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.

Reply via email to