Skip to content

strange things with eval and parent frames

2 messages · Mark Bravington, Peter Dalgaard

#
Thanks for the very quick and helpful explanation, Peter (and to Martin
Maechler for telling me about identical() ).

I'm still puzzled by the sys.call case. If I fake the issue by going one
level deeper, and then calling sys.call( sys.parent()) instead of
sys.call(), I do get what I expected to get (i.e. the call to the top-level
function). The example is:

test.parent.funcs3_ function() {
  subfunc3_ function() sys.call( -1) 
  x_ subfunc3(); print( x) # the top-level call
  
  subfunc3a_ function() eval( quote( sys.call()), parent.frame())
  x_ subfunc3a(); print( x) # I wanted the top level call, but the "eval"
gets intercepted
  
  subfunc3c_ function() eval( quote( { function() sys.call( sys.parent())
}() ), parent.frame())
  x_ subfunc3c(); print( x) # the top level call
}
test.parent.funcs3()
eval(expr, envir, enclos)
test.parent.funcs3()

The 3rd output line, which creates a temporary function and calls it,
"works" or at any rate is different from subfunc3a. The behaviour of
sys.call still seems inconsistent to me: if there's no way to pretend that
eval didn't happen, as you say, then isn't it a bug that you can fool the
system by going down a level and then up again? Actually I'd rather not have
the "fool" "bug" fixed, because it does give me a workround :), as follows:

my.sys.call_ function(which=0) {
  if( which==0)
    sys.call( sys.parent())
  else if( which<0)
    sys.call( which-1)
  else
    sys.call( which)
}

Note also:

test.parent.funcs4()_ function( ...) {
  subfunc1_ function() eval( quote( match.call()), envir=parent.frame())
  x_ subfunc1(); print( x)
}
test.parent.funcs4()

so that match.call works differently from sys.call here (it "ignores" the
call to eval).

cheers
Mark 

-----Original Message-----
From: Peter Dalgaard BSA
To: Mark.Bravington at csiro.au
Cc: r-help at stat.math.ethz.ch
Sent: 4/09/2002 4:14 PM
Subject: Re: [R] strange things with eval and parent frames

Mark.Bravington at csiro.au writes:
frames
<< deleted stuff >>
eval(
I
knock 1
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).
#
Mark.Bravington at csiro.au writes:
This stuff is fairly weird, and I definitely got something wrong:
parents are not the same as the "return addresses", as the examples in
help(sys.parents()) clearly show. (You might want to stick in a couple
of print(sys.status()) into your code to see what the system believes
that its state is).

There might in fact be a bug -- the logic of R_sysparent (in
context.c) does not look very robust against the case where several
elements on the context stack have the same cptr->cloenv (you
basically get the lowest numbered one in that case as far as I can
see). Or, then again, perhaps that is not a bug...; Robert Gentleman
is the expert on these matters.

(I'm not quite clear-headed enough today, but I think your 3c example
amounts to finding "the parent of my first incarnation" instead of "my
parent" by using the fact that "my first incarnation" is the parent of
my child....)