How can I access other scopes (NOT global)

How can I access other scopes (NOT global)

am 07.01.2008 18:47:51 von giblfiz

I was hoping that someone on the group might have an idea of how to
access scopes (or symbol tables) other than the one you are currently
running in. (and no I don't mean global)

In particular, I'm trying to use register_tick_function, and have the
function that it calls be able to get at variables in the scope of
what (otherwise) would currently be executing. Unfortunately the scope
of the function called by register_tick_function seems to be it's
own.

An example in code:

function a(){
$my_a = "mystery_value";
b();
}

function b(){
echo($my_a); //doesn't work
}

a();
?>

So I'm trying to figure out how to get at $my_a, none of the obvious
(to me) solutions are viable, I can't simply pass $my_a to b because b
is being called by a tick. I can't store $my_a in the globals because
I don't get to modify any of the code in a(). (I would be more than
happy with a solution where all scope variables were pushed into
global, but I can't think of a way to do this.


I realize that what I'm trying to do runs against the grain of what is
supposed to be legal in a language. (the whole point of scopes is to
protect you from whats in your parents) but I'm really hoping there is
a solution anyway. Ideally I would like to do this without loading the
ADB module, but if there is something in there that will help, I'm
open to that idea as well.

Re: How can I access other scopes (NOT global)

am 07.01.2008 18:50:23 von luiheidsgoeroe

On Mon, 07 Jan 2008 18:47:51 +0100, giblfiz wrote:

> I was hoping that someone on the group might have an idea of how to
> access scopes (or symbol tables) other than the one you are currently
> running in. (and no I don't mean global)

You can't, you either have to pass the variable, or a reference to it.
--
Rik Wasmus

Re: How can I access other scopes (NOT global)

am 07.01.2008 19:32:45 von Michael Fesser

..oO(giblfiz)

>I was hoping that someone on the group might have an idea of how to
>access scopes (or symbol tables) other than the one you are currently
>running in. (and no I don't mean global)
>
>In particular, I'm trying to use register_tick_function, and have the
>function that it calls be able to get at variables in the scope of
>what (otherwise) would currently be executing. Unfortunately the scope
>of the function called by register_tick_function seems to be it's
>own.

Correct. That's how it works in almost every language.

>An example in code:
> >
>function a(){
> $my_a = "mystery_value";
> b();
>}
>
>function b(){
> echo($my_a); //doesn't work
>}
>
>a();
>?>
>
>So I'm trying to figure out how to get at $my_a, none of the obvious
>(to me) solutions are viable, I can't simply pass $my_a to b because b
>is being called by a tick. I can't store $my_a in the globals because
>I don't get to modify any of the code in a(). (I would be more than
>happy with a solution where all scope variables were pushed into
>global, but I can't think of a way to do this.

What about OOP? Putting a() and b() into a class would give you kind of
a common namespace for both.

And what about a() - are you not able to modify it or do you just don't
want to modify it? If the code of a() is "fixed", how is this entire
thing supposed to work? Without some ugly hacking it would be impossible
in almost every language. Maybe you can post some more details about
what this whole thing is about and what you're trying to accomplish.

Micha

Re: How can I access other scopes (NOT global)

am 07.01.2008 20:43:26 von giblfiz

I'm trying to write an "introspective debugger" file. (it's tempting
to use the word class, but it's just not true.) The idea being that
you include the file at the beginning of your all ready written code,
add a few STOP statements, and then visit you script as normal. Only
now you get a simple ajax debugger which lets you view source files,
your stack, step through the code, resume operation (to next STOP),
and watch variables.

Sounds impossible? Sounds insane? Using some of the less well known
PHP functions, and some tricks with sockets I have figured out how to
do all of this except for watching variables that are not globals.
(take a look at register_tick_function, and at debug_backtrace and
then think about it for a few seconds, most of what I'm talking about
is actually in there)

So in answer to your question, no I CAN'T modify a(), because a() is
actually pretty much every function in the program. (since b() is
being called on every tick, from every function and every method) I
should have realized that by putting that a() b() example into place
people were going to assume that it was actually my situation. My
actual situation is:


register_tick_function("ticker");

ticker(){
$my_var_in_ticker_scope = "known value";
var_dump(get_defined_vars());
var_dump(debug_backtrace());
}

declare(ticks=1);

a(){
$my_a = "mystery value";
1+1;
}

a();

?>

So there is a point, right about when 1+1 is being run, when ticker
will be called and its results will be:
A dump of all the variables in the global scope, and
$my_var_in_ticker_scope, and a dump of the stack which will more or
less say:

2) Ticker()
1) a()

My best bet before was trying
register_tick_function(Ticker,get_defined_vars()), but this evaluates
get_defined_vars() once, when register_tick_function is called, not
every time ticker gets called. (this behavior seems obvious to me in
retrospect, but maybe someone knows how force it to be re-evaluated on
a run by run basis. nothing I know of in the language can do this)

Right now I have three "best bets":
1) Possibly throwing a user defined error, and then seeing what scopes
can be reached as part of a user defined error handler. (I haven't
played with this yet, but it strikes me as a longshot)
2) A similar idea using throw and catch. I am even less enthusiastic
about this idea because it pulls you down out of your current scope in
an unrecoverable way. But if there is a way to register a catch block
that is universal, that would work.
3) Perhaps there is something really interesting that can be done
using eval. I haven't really thought about it too deeply yet.

I'm also open to any other ideas, if anyone has any.