In the recent discussion about patching, a question about patching a function f including local variables of a module or another function was discussed. For example, let it be defined as

A:=proc() global f,t; local x,y,z;
f:=()->x+y();
y:=()->z;
t:=()->x+z;
x,z:=0,1;
NULL end:
A();

Now,

op(f);
                            () -> x + y()
f();
                                  1

How to change it so that it would return 2 instead of 1, without reassigning it?

I'll do that here by changing the value of z (which is a local variable of procedure A) using the lexical table of f (see ?proc, op 7).

We can't see z in

L:=op(7,op(f));
                           L := x, x, y, y
%;
                              x, 0, y, y

It would be easier to change x, but for the purpose of this example, I'd like to change the value of z. Being a part of definition of y, it can be seen in

op(7,op(L[4]));
                                 z, z
%;
                                 z, 1

That, by the way, shows that elements in lexical tables go in pairs - first the global variable, then the local variable. In other words, the local z that we need is

op([7,2],op(op([7,4],op(f))));
                                  z
%;
                                  1

Now we can reassign it to 2,

assign(op([7,2],op(op([7,4],op(f)))), 2);
op(f);
                            () -> x + y()
f();
                                  2

That affects t as well,

op(t);
                             () -> x + z
t();
                                  2

(So another way of doing that would be to use the same trick for t instead of f which is easier, and that would affect f as well.)

Alec


Please Wait...