[Bioc-devel] Lazy evaluation and S4 methods

Kevin Ushey kevinushey at gmail.com
Wed Apr 23 22:04:47 CEST 2014


Thanks Michael -- that looks quite useful.

Is my other conjecture true though -- S4 methods are evaluated in an
environment detached from the caller, so that regular symbol lookup
does not work as it might for regular functions? Or why do I see that
behaviour?

Kevin

On Wed, Apr 23, 2014 at 11:13 AM, Michael Lawrence
<lawrence.michael at gene.com> wrote:
> The tricky part about your example is that each of the arguments in "..."
> could be originating from different frames.
>
> The S4Vectors:::top_prenv_dots function will give you a list of
> environments, one for each argument in "...". An example of its use can be
> found in IRanges::transform.DataTable.
>
> I bet top_prenv_dots will be moving to a different package soon, so don't
> get too attached to anything.
>
> Michael
>
>
>
>
>
> On Wed, Apr 23, 2014 at 11:02 AM, Kevin Ushey <kevinushey at gmail.com> wrote:
>>
>> Hi everyone,
>>
>> I'm trying to investigate lazy evaluation with S4, and specifically
>> the environment chain available for lookup when an S4 method is
>> evaluated.
>>
>> With 'vanilla' R functions, we can write something like the following:
>>
>>     lazy <- function(...) {
>>       call <- substitute(list(...))
>>       for (i in 2:length(call)) {
>>         eval(call[[i]])
>>       }
>>     }
>>
>> and evaluation will succeed if this function is called by another
>> function:
>>
>>     f <- function() {
>>       var <- 10
>>       lazy(x = var)
>>     }
>>
>>     f()
>>
>> The evaluation of the symbol 'var' is able to find it in the 'f'
>> environment.
>>
>>     setClass("Lazy", list(data="list"))
>>     setGeneric("lazy", function(x, ...) standardGeneric("lazy"))
>>     setMethod("lazy", list(x="Lazy"), function(x, ...) {
>>       call <- substitute(list(...))
>>       for (i in 2:length(call)) {
>>         eval( call[[i]] )
>>       }
>>     })
>>
>>     f <- function() {
>>       var <- new("Lazy", data=list(1))
>>       y <- 1
>>       cat("\n")
>>       lazy(var, a=y)
>>     }
>>
>>     f()
>>
>> gives ' Error in eval(expr, envir, enclos) : object 'y' not found '.
>> It seems like the S4 method is evaluated in an environment detached
>> from the scope of the caller (which is probably outlined in ?Methods,
>> but I am having trouble parsing everything in there).
>>
>> My main question is -- is there a nice way to work around this, in a
>> way that is transparent to the user of a function?
>>
>> Further motivation available in the GitHub issue for flowCore here:
>> https://github.com/RGLab/ncdfFlow/issues/31
>>
>> Thanks,
>> Kevin
>>
>> _______________________________________________
>> Bioc-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/bioc-devel
>
>



More information about the Bioc-devel mailing list