[Rd] parent.frame(1) of a S4 method is not a calling environment.
Dear Developers, I wonder what are the parent.frame rules for methods. For ordinary functions one can call parent.frame() and be sure that it is the environment of a calling function. With S4 aparently it is not the case. Here is what I have discovered by trial and error so far: > setClass("A", contains="vector") [1] "A" > setGeneric("foo", def=function(a, ...){standardGeneric("foo")}) [1] "foo" > > setMethod("foo", signature("A"), + def=function(a, ...){ + cat("--pf1--\n") + ls(parent.frame(1)) + ## cat("--pf2--") + ## ls(parent.frame(2)) + }) [1] "foo" > > tf <- function(){ + b <- 4 + foo(new("A")) #ok + } > > tf() #ok --pf1-- [1] "b" The above works like predicted. Now, a small change. The "b" argument which is not in the signature, but has a role of an additional parameter to the function: > setMethod("foo", signature("A"), + def=function(a, b, ...){ + cat("--pf1--\n") + print(ls(parent.frame(1))) + cat("--pf2--\n") + print(ls(parent.frame(2))) + }) [1] "foo" > > tf() #oups --pf1-- [1] "a" --pf2-- [1] "b" > So, can I be sure that for such functions parent.frame(2) will always work? What are the additional rules? Many thanks, Vitaly. __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] parent.frame(1) of a S4 method is not a calling environment.
Martin Morgan writes: >> >> So, can I be sure that for such functions parent.frame(2) will always work? >> What are the additional rules? > > callNextMethod() will cause additional problems; the idea that you'll > grab things from somewhere other than function arguments doesn't seem > like a robust design, even if it's used in some important parts of R. > > Martin > That make it difficult to handle unevaluated expressions in methods. A solution would be to explicitly require the users to use quote() or expression(), and then to use the "expression" in the signature. Slightly unpleasant, though. Standardised, simpler syntax like .() in ggplot and plyr, would be handy here. Hopefully .() is not grabbed for something else in meanwhile:). Vitaly. __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] parent.frame(1) of a S4 method is not a calling environment.
Duncan Murdoch writes: > Vitaly S. wrote: >> Martin Morgan writes: >> >>>> So, can I be sure that for such functions parent.frame(2) will always >>>> work? >>>> What are the additional rules? >>>> >>> callNextMethod() will cause additional problems; the idea that you'll >>> grab things from somewhere other than function arguments doesn't seem >>> like a robust design, even if it's used in some important parts of R. >>> >>> Martin >>> >>> >> >> That make it difficult to handle unevaluated expressions in methods. A >> solution >> would be to explicitly require the users to use quote() or expression(), and >> then to use the "expression" in the signature. Slightly unpleasant, though. >> >> > > You could use formulas for that. If you pass in > > formula = ~ x + y*z > > then environment(formula) will be the right evaluation environment, and > formula[[2]] will be the unevaluated x + > y*z. > > Duncan Murdoch Thank you Duncan, I didn't know that. For programmatic use though, formula interface is slightly inconvenient. A specialized function and class would be desirable. With the advent of more and more complex S4 classes, unevaluated expressions in methods calls will became a necessity, that's my feeling. Thank you. Vitaly. > >> Standardised, simpler syntax like .() in ggplot and plyr, would be handy >> here. >> Hopefully .() is not grabbed for something else in meanwhile:). >> >> Vitaly. >> >> __ >> R-devel@r-project.org mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel >> __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] parent.frame(1) of a S4 method is not a calling environment.
Hadley Wickham writes: > On Tuesday, August 17, 2010, Vitaly S. wrote: >> Duncan Murdoch writes: >> >>> Vitaly S. wrote: >>>> Martin Morgan writes: >>>> >>>>>> So, can I be sure that for such functions parent.frame(2) will always >>>>>> work? >>>>>> What are the additional rules? >>>>>> >>>>> callNextMethod() will cause additional problems; the idea that you'll >>>>> grab things from somewhere other than function arguments doesn't seem >>>>> like a robust design, even if it's used in some important parts of R. >>>>> >>>>> Martin >>>>> >>>>> >>>> >>>> That make it difficult to handle unevaluated expressions in methods. A >>>> solution >>>> would be to explicitly require the users to use quote() or expression(), >>>> and >>>> then to use the "expression" in the signature. Slightly unpleasant, though. >>>> >>>> >>> >>> You could use formulas for that. If you pass in >>> >>> formula = ~ x + y*z >>> >>> then environment(formula) will be the right evaluation environment, and >>> formula[[2]] will be the unevaluated x + >>> y*z. >>> >>> Duncan Murdoch >> >> Thank you Duncan, I didn't know that. >> >> For programmatic use though, formula interface is slightly inconvenient. A >> specialized function and class would be desirable. With the advent of more >> and >> more complex S4 classes, unevaluated expressions in methods calls will >> became a >> necessity, that's my feeling. > > I probably should move the quoting related out of plyr into it's own > package to facilitate this type of reuse. I think the current > structure is quite general. That would be neat. An S4 class "quote" which would store the parent.frame as a slot would be great! > > Hadley __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
Re: [Rd] c.POSIXct
Spencer Graves writes: >I'm with Gabor on this. I naively would not expect c() to strip > attributes generally, and I've been > surprise more than once to find the time zone attribute stripped when I did > not expect that. > > > Might it make sense to add an argument like "keepAttributes=FALSE" to > the "c" function? Then people like > Gabor and me would know that we would have to specify "keepAttributes = TRUE" > if we wanted attributes to be kept. I often find myself using c() just to strip attributes when manipulating arrays in simulation. c() is probably already quite complex function, "keepAttributes=FALSE" would complicate it even more and impact the speed. Given that, I wonder why there is no dedicated function to strip attributes. Am I missing anything? Vitaly. __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
[Rd] lapply version with [ subseting - a suggestion
Dear R developers, Reviewing my code, I have realized that about 80% of the time in the lapply I need to access the names of the objects inside the loop. In such cases I iterate over indexes or names: lapply(names(x), ... [i]), lapply(seq_along(x), ... x[[i]] ... names(x)[i] ), or for(i in seq_along(x)) ... which is rather inconvenient. How about an argument to lapply which would specify the [ or [[ subseting to use in the splitting of the vector? Or may be a different set of functions lapply1, sapply1? I believe this pattern is rather common for other users as well. Thanks. VS. __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel
[Rd] new.env does not recognize parents from subclasses of "environment"
Dear Developers, A lot has been changed in the R12.0 with respect to behavior of "environment" subclasses. Many thanks for that. One small irregularity, though; new.env does not allow the parent to be from S4 subclass. > setClass("myenv", contains="environment") [1] "myenv" > new.env(parent=new("myenv")) Error in new.env(parent = new("myenv")) : 'enclos' must be an environment I wonder if this is a "planed" behavior. The use of .xData slot obviously works: > new.env(parent=new("myenv")@.xData) > Thanks, Vitaly. __ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel