[R] strange things with eval and parent frames

Peter Dalgaard BSA p.dalgaard at biostat.ku.dk
Wed Sep 4 08:14:40 CEST 2002


Mark.Bravington at csiro.au writes:

> Dear mailing list,
> 
> I have found some strange behaviour which I think relates to parent frames
> and eval. Can anyone explain what's going on here? 
> 
> First example:
> 
> > test.parent.funcs_ function() {
>   outer.var_ 5
>   subfunc1_ function() substitute( outer.var, envir=parent.frame())
>   print( subfunc1())
> 
>   subfunc2b_ function() eval( quote( outer.var), envir=parent.frame())
>   print( subfunc2b())
>   
>   subfunc2_ function() evalq( outer.var, envir=parent.frame()) 
>   #print( subfunc2())
> }
> 
> > test.parent.funcs()
> [1] 5
> [1] 5
> 
> If you try this without the hash before the 3rd print statement, it crashes,
> complaining it can't find outer.var. But AFAICS, subfunc2 and subfunc2b
> should return the same thing. So, at a minimum, evalq(...) doesn't seem to
> be behaving the same as eval( quote(...)) as the documentation says it
> should. But I think more fundamentally odd things are happening, as per
> below.
> 
> Note BTW that this is NOT a classical scoping problem. Exactly the same
> things happen if I define subfunc1 etc. outside the body of
> test.parent.funcs.

This is a bug, but not an easy one to fix: Internally, evalq does

eval.parent(substitute(eval(quote(expr), envir, enclos)))

which works for any envir except if the expression for it involves
parent.frame. The generic problem is that normally
eval.parent(substitute(x)) is equivalent to x but if there's an
examination of the call stack involved (using sys.call() or
parent.frame() etc.) they are not... 

You can work around it with

function() {p<-parent.frame();evalq( outer.var, envir=p) }


> Second example:
> > test.parent.funcs2_ function() {
>   subfunc3_ function() sys.call( -1)
>   x_ subfunc3(); print( x)
>   
>   subfunc3a_ function() eval( quote( sys.call()), parent.frame())
>   x_ subfunc3a(); print( x)
>   
>   subfunc3b_ function() evalq( sys.call(), parent.frame())
>   x_ subfunc3b(); print( x)
> }
> 
> > test.parent.funcs2()
> test.parent.funcs2()
> eval(expr, envir, enclos)
> eval(expr, envir, enclos)
> 
> Hmmm. Again, I'd expect all three to do the same thing (have I
> misunderstood?). What's even more odd, is that this time evalq and eval(
> quote()) do coincide, but neither of them gives the answer I expected. I
> thought that by doing the evaulation in the parent.frame, I could knock 1
> level off the number of generations to go back in sys.call.

This one is not a bug. There's just no way that you can make the
system pretend that the call to eval() or evalq() didn't happen. (And
sys.call() is independent of evaluation environment, so the
parent.frame() anomaly doesn't matter).

-- 
   O__  ---- Peter Dalgaard             Blegdamsvej 3  
  c/ /'_ --- Dept. of Biostatistics     2200 Cph. N   
 (*) \(*) -- University of Copenhagen   Denmark      Ph: (+45) 35327918
~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk)             FAX: (+45) 35327907
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-help mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !)  To: r-help-request at stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._



More information about the R-help mailing list