Re: Replacing a single function/method in an existing live class?

2021-05-02 Thread Chris Angelico
On Mon, May 3, 2021 at 4:25 AM Stephen R. van den Berg  wrote:
>
> Chris Angelico wrote:
> >My usual practice is to completely recompile the class, and have a
> >single mapping for all "carry-over" state, something like this:
>
> >And then to replace anything, I'd create a new instance of the
> >newly-compiled class, replace its empty state mapping with the same
> >one as the old object, and start using that. It's simple, reliable,
>
> Yes, if the class in completely in the source you control, that is fine.
> But in this case the class comes from a sort-of library (from which
> I inherit), and there is more state information than just the config, like:
>
> - Caches.
> - Database connection pools.
> - Active sockets.
> - Active sessions.
> - Various call_out timers still pending.
> - Statistics.
>

Ah, that does make it more complicated. Particularly with call_outs.

I don't think there's an easy way to do this.

ChrisA


Re: Replacing a single function/method in an existing live class?

2021-05-02 Thread Stephen R. van den Berg
Chris Angelico wrote:
>My usual practice is to completely recompile the class, and have a
>single mapping for all "carry-over" state, something like this:

>And then to replace anything, I'd create a new instance of the
>newly-compiled class, replace its empty state mapping with the same
>one as the old object, and start using that. It's simple, reliable,

Yes, if the class in completely in the source you control, that is fine.
But in this case the class comes from a sort-of library (from which
I inherit), and there is more state information than just the config, like:

- Caches.
- Database connection pools.
- Active sockets.
- Active sessions.
- Various call_out timers still pending.
- Statistics.

-- 
Stephen.


Re: Replacing a single function/method in an existing live class?

2021-05-02 Thread Chris Angelico
On Mon, May 3, 2021 at 3:35 AM Stephen R. van den Berg  wrote:
>
> Lance Dillon wrote:
> >The closest I could see is to not really have the functions directly, I 
> >guess, but an mapping of functions, and overload `() so that it pulls the 
> >function from the mapping, then you could easily replace the function by 
> >replacing the reference in the mapping.
> >The replaced function would be locator collected,or you could implement it 
> >as a list of hooks.
> >Could be transparent to calling code and be effectively the same thing, even 
> >if implemented differently.
> >Unless I am misunderstanding how `() works.
>
> I think that method breaks at the point where you need to manipulate "this"
> to point to the main class.
>
> Ah well, I am restructuring the code so that the live class in question
> is being referenced through a variable.  It seems that is the only
> practical solution.

My usual practice is to completely recompile the class, and have a
single mapping for all "carry-over" state, something like this:

class A {
mapping s = ([]);
void B() {...}
void C() {...}
}

And then to replace anything, I'd create a new instance of the
newly-compiled class, replace its empty state mapping with the same
one as the old object, and start using that. It's simple, reliable,
and safe (if any old code is still referenced, it'll use the same
state mapping), and doesn't require weird shenanigans.

It might be kinda nice to have some sort of compiler support for
changing the 'this' context of a function, but it's really not
something that I'd use very often.

ChrisA


Re: Replacing a single function/method in an existing live class?

2021-05-02 Thread Stephen R. van den Berg
Lance Dillon wrote:
>The closest I could see is to not really have the functions directly, I guess, 
>but an mapping of functions, and overload `() so that it pulls the function 
>from the mapping, then you could easily replace the function by replacing the 
>reference in the mapping.
>The replaced function would be locator collected,or you could implement it as 
>a list of hooks.
>Could be transparent to calling code and be effectively the same thing, even 
>if implemented differently.
>Unless I am misunderstanding how `() works.

I think that method breaks at the point where you need to manipulate "this"
to point to the main class.

Ah well, I am restructuring the code so that the live class in question
is being referenced through a variable.  It seems that is the only
practical solution.
-- 
Stephen.


Re: Replacing a single function/method in an existing live class?

2021-05-02 Thread Lance Dillon
The closest I could see is to not really have the functions directly, I guess, 
but an mapping of functions, and overload `() so that it pulls the function 
from the mapping, then you could easily replace the function by replacing the 
reference in the mapping.
The replaced function would be locator collected,or you could implement it as a 
list of hooks.
Could be transparent to calling code and be effectively the same thing, even if 
implemented differently.
Unless I am misunderstanding how `() works.

Sent from Yahoo Mail on Android 
 
  On Sun, May 2, 2021 at 12:32 PM, Stephen R. van den Berg wrote: 
  Chris Angelico wrote:
>trying to do won't work with injection. But perhaps subclassing can do
>what you want - instead of compiling the entire class again, create a
>subclass that replaces that one function.

Yes, well, that won't cut it, I'm afraid, because I specifically want
that function to be able to pretend that he is living inside the
already live/running older object of the old class (needs access to
those variables/members).

I'm trying to see how close I can get to rapid development where you
actually replace methods inside live classes during runtime.

On a related question then, if I do this:

class D {
  class E {
    void F() {
    }
  }
  function G() {
    E e = E();
    return e->F;
  }
}

int main() {
  D d = D();
  function ref = d->G();
  d = 0;
  gc();
  // At this point, does object d still
  // have references?
  // Or is it gone because from F
  // we do not refrence D?
  return 0;
}
-- 
Stephen.
  


Re: Replacing a single function/method in an existing live class?

2021-05-02 Thread Stephen R. van den Berg
Chris Angelico wrote:
>trying to do won't work with injection. But perhaps subclassing can do
>what you want - instead of compiling the entire class again, create a
>subclass that replaces that one function.

Yes, well, that won't cut it, I'm afraid, because I specifically want
that function to be able to pretend that he is living inside the
already live/running older object of the old class (needs access to
those variables/members).

I'm trying to see how close I can get to rapid development where you
actually replace methods inside live classes during runtime.

On a related question then, if I do this:

class D {
  class E {
void F() {
}
  }
  function G() {
E e = E();
return e->F;
  }
}

int main() {
  D d = D();
  function ref = d->G();
  d = 0;
  gc();
  // At this point, does object d still
  // have references?
  // Or is it gone because from F
  // we do not refrence D?
  return 0;
}
-- 
Stephen.


Re: Replacing a single function/method in an existing live class?

2021-05-02 Thread Chris Angelico
On Mon, May 3, 2021 at 2:04 AM Stephen R. van den Berg  wrote:
>
> Say I have this:
>
> class A {
>   int k;
>   void B() {
> write("foo %d\n", k);
>   }
>   void C() {
> k = 3;
> write("bar\n");
>   }
> }
>
> int main() {
>   A a = A();
>   a->C();   // Displays: bar
>   a->B();   // Displays: foo 3
>   // At this point I want to replace the function B
>   // in the running/compiled instance of A in a.
>   //  I.e. I want to call compile() or similar
>   //  on the following code:
>   //void B() { write("FOO %d\n", k); }
>   //  such that I can subsequently run:
>   a->B();  // Should display: FOO 3
>   return 0;
> }
>
> Any way this can be accomplished?
> An alternate way would be to compile the whole class of A again, but
> then run method B() in it with a custom this argument pointing to the
> old instance in a.  Is that possible?  I know javascript can do this,
> but it seems like Pike does not allow/support it.

JavaScript has some utterly bizarre rules about the 'this' reference
that I wouldn't want to see any other language replicate. In Pike, a
function remembers the context it was created in, so what you're
trying to do won't work with injection. But perhaps subclassing can do
what you want - instead of compiling the entire class again, create a
subclass that replaces that one function.

ChrisA


Replacing a single function/method in an existing live class?

2021-05-02 Thread Stephen R. van den Berg
Say I have this:

class A {
  int k;
  void B() {
write("foo %d\n", k);
  }
  void C() {
k = 3;
write("bar\n");
  }
}

int main() {
  A a = A();
  a->C();   // Displays: bar
  a->B();   // Displays: foo 3
  // At this point I want to replace the function B
  // in the running/compiled instance of A in a.
  //  I.e. I want to call compile() or similar
  //  on the following code:
  //void B() { write("FOO %d\n", k); }
  //  such that I can subsequently run:
  a->B();  // Should display: FOO 3
  return 0;
}

Any way this can be accomplished?
An alternate way would be to compile the whole class of A again, but
then run method B() in it with a custom this argument pointing to the
old instance in a.  Is that possible?  I know javascript can do this,
but it seems like Pike does not allow/support it.
-- 
Stephen.