Observing changes of regular attributes

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Observing changes of regular attributes

Peter Uhnak
Hi,

is there a mechanism for observing a change of regular variables?

Normally I would use ValueHolder (or fire announcements manually), but this assumes I can change the code.

For example imagine a method of someone else's package
~~~~~~~~~~~~~~~
FAMIXNamedEntity>>name: aString
    name := aString
~~~~~~~~~~~~~~~

I could simply override the method, but that's very brittle since if I were to update the package it would load the "unmodified" version.

Can I somehow overload the assignment operator? Can I augment methods? Is this even possible?

Thanks,
Peter
Reply | Threaded
Open this post in threaded view
|

Re: Observing changes of regular attributes

stepharo
Not yet :)

Le 9/9/15 18:18, Peter Uhnák a écrit :

> Hi,
>
> is there a mechanism for observing a change of regular variables?
>
> Normally I would use ValueHolder (or fire announcements manually), but
> this assumes I can change the code.
>
> For example imagine a method of someone else's package
> ~~~~~~~~~~~~~~~
> FAMIXNamedEntity>>name: aString
>     name := aString
> ~~~~~~~~~~~~~~~
>
> I could simply override the method, but that's very brittle since if I
> were to update the package it would load the "unmodified" version.
>
> Can I somehow overload the assignment operator? Can I augment methods?
> Is this even possible?
>
> Thanks,
> Peter


Reply | Threaded
Open this post in threaded view
|

Re: Observing changes of regular attributes

Mariano Martinez Peck
If you can live with only intercepting setters (not assigments) , then you can run some code AFTER loading the code, to install some method wrappers or Marea CompiledMethod proxy that intercept the execution of the setter method and do whatever you want. In the worst case you simply must re-run such script after reloading the code .... 



On Wed, Sep 9, 2015 at 3:27 PM, stepharo <[hidden email]> wrote:
Not yet :)

Le 9/9/15 18:18, Peter Uhnák a écrit :

Hi,

is there a mechanism for observing a change of regular variables?

Normally I would use ValueHolder (or fire announcements manually), but this assumes I can change the code.

For example imagine a method of someone else's package
~~~~~~~~~~~~~~~
FAMIXNamedEntity>>name: aString
    name := aString
~~~~~~~~~~~~~~~

I could simply override the method, but that's very brittle since if I were to update the package it would load the "unmodified" version.

Can I somehow overload the assignment operator? Can I augment methods? Is this even possible?

Thanks,
Peter





--
Reply | Threaded
Open this post in threaded view
|

Re: Observing changes of regular attributes

Thierry Goubier
Le 09/09/2015 21:00, Mariano Martinez Peck a écrit :
> If you can live with only intercepting setters (not assigments) , then
> you can run some code AFTER loading the code, to install some method
> wrappers or Marea CompiledMethod proxy that intercept the execution of
> the setter method and do whatever you want. In the worst case you simply
> must re-run such script after reloading the code ....

You can also use Jejak to trace assignments with the same approach (i.e.
to reinstall the probes after loading a new version), but you'll have to
adapt one of the Jejak rewriter for that (or filter the generated events
to retrieve only the ones relevant to your instance variable).

By the way, Marcus, how do Metalinks behave in this scenario (i.e.
reloading a new version of the code). Are they lost?

Thierry

>
>
> On Wed, Sep 9, 2015 at 3:27 PM, stepharo <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Not yet :)
>
>     Le 9/9/15 18:18, Peter Uhnák a écrit :
>
>         Hi,
>
>         is there a mechanism for observing a change of regular variables?
>
>         Normally I would use ValueHolder (or fire announcements
>         manually), but this assumes I can change the code.
>
>         For example imagine a method of someone else's package
>         ~~~~~~~~~~~~~~~
>         FAMIXNamedEntity>>name: aString
>              name := aString
>         ~~~~~~~~~~~~~~~
>
>         I could simply override the method, but that's very brittle
>         since if I were to update the package it would load the
>         "unmodified" version.
>
>         Can I somehow overload the assignment operator? Can I augment
>         methods? Is this even possible?
>
>         Thanks,
>         Peter
>
>
>
>
>
>
> --
> Mariano
> http://marianopeck.wordpress.com


Reply | Threaded
Open this post in threaded view
|

Re: Observing changes of regular attributes

Marcus Denker-4

> On 09 Sep 2015, at 21:26, Thierry Goubier <[hidden email]> wrote:
>
> Le 09/09/2015 21:00, Mariano Martinez Peck a écrit :
>> If you can live with only intercepting setters (not assigments) , then
>> you can run some code AFTER loading the code, to install some method
>> wrappers or Marea CompiledMethod proxy that intercept the execution of
>> the setter method and do whatever you want. In the worst case you simply
>> must re-run such script after reloading the code ....
>
> You can also use Jejak to trace assignments with the same approach (i.e. to reinstall the probes after loading a new version), but you'll have to adapt one of the Jejak rewriter for that (or filter the generated events to retrieve only the ones relevant to your instance variable).
>
> By the way, Marcus, how do Metalinks behave in this scenario (i.e. reloading a new version of the code). Are they lost?
>
Yes, re-applying links needs to be done by the user for now. I should add a framwork and example to make this easier.

        Marcus


Reply | Threaded
Open this post in threaded view
|

Re: Observing changes of regular attributes

Marcus Denker-4
In reply to this post by Peter Uhnak
Hello,

The idea of Reflectivity is to be just that: a way to “hook” into code without changing the source… this is a similar use case like
the one described yesterday:

link := MetaLink new
        metaObject: MyNotifyer;
        selector: #notifyChangedVaNamed:;
        arguments: #(name).
       
this is a link that when installed on an AssignmentNode, will call #notifyChangedVaNamed on a class MyNotifyer
with the name of the changed variable passed as an argument. (you can pass other things needed, one could
even have an Announcement as the metaObject.

To install this on all ivar assignments, do:

MyClass assignmentNodes do: [ :each | each variable isInstance ifTrue: [each link: link ]].

to get rid of the link:

link uninstall.

Now when code is recompiled (loaded), you need to re-install the links in those methods, it does not happen
automatically.

        Marcus

> On 09 Sep 2015, at 18:18, Peter Uhnák <[hidden email]> wrote:
>
> Hi,
>
> is there a mechanism for observing a change of regular variables?
>
> Normally I would use ValueHolder (or fire announcements manually), but this assumes I can change the code.
>
> For example imagine a method of someone else's package
> ~~~~~~~~~~~~~~~
> FAMIXNamedEntity>>name: aString
>     name := aString
> ~~~~~~~~~~~~~~~
>
> I could simply override the method, but that's very brittle since if I were to update the package it would load the "unmodified" version.
>
> Can I somehow overload the assignment operator? Can I augment methods? Is this even possible?
>
> Thanks,
> Peter


Reply | Threaded
Open this post in threaded view
|

Re: Observing changes of regular attributes

Peter Uhnak


On Wed, Sep 9, 2015 at 10:04 PM, Marcus Denker <[hidden email]> wrote:
Hello,

The idea of Reflectivity is to be just that: a way to “hook” into code without changing the source… this is a similar use case like
the one described yesterday:

link := MetaLink new
        metaObject: MyNotifyer;
        selector: #notifyChangedVaNamed:;
        arguments: #(name).

Ah, this is really cool and powerful, thanks!

I imagine in time tools will be built to have better control of this (for example now stack trace in debugger looks really magical (suddenly there's a frame from nowhere)), but all in time.

Now when code is recompiled (loaded), you need to re-install the links in those methods, it does not happen
automatically.

Are there any scenarios when method is recompiled during regular Pharo run and without user's invocation? In other words, if I install the links after the package has been loaded/updated and I will not be changing the code, will I be safe?

Also I am little bit scared that without tools I am brewing a recipe for disaster, because this is very powerful and not controlled... maybe I should do real AST rewrites and recompile instead... or investigate if I can somehow annotate Nautilus and debugger to show the links... hmm...

Peter
Reply | Threaded
Open this post in threaded view
|

Re: Observing changes of regular attributes

Marcus Denker-4

On 10 Sep 2015, at 19:45, Peter Uhnák <[hidden email]> wrote:



On Wed, Sep 9, 2015 at 10:04 PM, Marcus Denker <[hidden email]> wrote:
Hello,

The idea of Reflectivity is to be just that: a way to “hook” into code without changing the source… this is a similar use case like
the one described yesterday:

link := MetaLink new
        metaObject: MyNotifyer;
        selector: #notifyChangedVaNamed:;
        arguments: #(name).

Ah, this is really cool and powerful, thanks!

I imagine in time tools will be built to have better control of this (for example now stack trace in debugger looks really magical (suddenly there's a frame from nowhere)), but all in time.

Yes! One thing I want to add is to visualise links in the debugger (so that you can explore easily who hooked into what).  And provide a “step into meta”. functionality.

Now when code is recompiled (loaded), you need to re-install the links in those methods, it does not happen
automatically.

Are there any scenarios when method is recompiled during regular Pharo run and without user's invocation?
If nobody else does magic, just loading code or editing code.

In other words, if I install the links after the package has been loaded/updated and I will not be changing the code, will I be safe?

If you want to be sure, you need to implement a layer above. (I want to provide a framework for that later to be reused)

-> Every change to code can be easily tracked by subscribing to the system notification mechanism
-> If a method changed that you are interested in —> reinstall the links.

Also I am little bit scared that without tools I am brewing a recipe for disaster, because this is very powerful and not controlled…
Indeed,

maybe I should do real AST rewrites and recompile instead... or investigate if I can somehow annotate Nautilus and debugger to show the links... hmm…

Link visualisation in the code will come, now with the new editor this is actually possible! But it will be after the whole base is stable and debugged...
But of course the “hidden” nature of the metalink is a tradeoff… rewriting code in a more visible way can be better depending on the situation.

Marcus
 

Reply | Threaded
Open this post in threaded view
|

Re: Observing changes of regular attributes

Peter Uhnak
I imagine in time tools will be built to have better control of this (for example now stack trace in debugger looks really magical (suddenly there's a frame from nowhere)), but all in time.
Yes! One thing I want to add is to visualise links in the debugger (so that you can explore easily who hooked into what).  And provide a “step into meta”. functionality. 

I'm currently looking into debuggers to at least provide reference in the context... but this may not be achievable without code rewrite...

 
Now when code is recompiled (loaded), you need to re-install the links in those methods, it does not happen
automatically.

Are there any scenarios when method is recompiled during regular Pharo run and without user's invocation?
If nobody else does magic, just loading code or editing code.

That should be fine then... I hope. :) 


In other words, if I install the links after the package has been loaded/updated and I will not be changing the code, will I be safe?

If you want to be sure, you need to implement a layer above. (I want to provide a framework for that later to be reused)

-> Every change to code can be easily tracked by subscribing to the system notification mechanism
-> If a method changed that you are interested in —> reinstall the links.

I wanted to avoid global subscriptions since I am not sure of the performance penalty... it seems to me like a overkill, but someone would have to benchmark it first. Because 99% of the time you are probably not working with MetaLinks.

maybe I should do real AST rewrites and recompile instead... or investigate if I can somehow annotate Nautilus and debugger to show the links... hmm…

Link visualisation in the code will come, now with the new editor this is actually possible! But it will be after the whole base is stable and debugged...
But of course the “hidden” nature of the metalink is a tradeoff… rewriting code in a more visible way can be better depending on the situation.

Well since I want to play with metalinks some more I created a simple Nautilus plugin that can show MetaLinks associated with a method... 


But I don't know how useful it would be for real metalink usage... maybe I can publish it somewhere...

Peter
Reply | Threaded
Open this post in threaded view
|

Re: Observing changes of regular attributes

Marcus Denker-4


In other words, if I install the links after the package has been loaded/updated and I will not be changing the code, will I be safe?

If you want to be sure, you need to implement a layer above. (I want to provide a framework for that later to be reused)

-> Every change to code can be easily tracked by subscribing to the system notification mechanism
-> If a method changed that you are interested in —> reinstall the links.

I wanted to avoid global subscriptions since I am not sure of the performance penalty... it seems to me like a overkill, but someone would have to benchmark it first. Because 99% of the time you are probably not working with MetaLinks.

I should build some mechanism where the notification is done somehow by the method… it knows its links and the links could know who installed them and notify to re-install.

maybe I should do real AST rewrites and recompile instead... or investigate if I can somehow annotate Nautilus and debugger to show the links... hmm…

Link visualisation in the code will come, now with the new editor this is actually possible! But it will be after the whole base is stable and debugged...
But of course the “hidden” nature of the metalink is a tradeoff… rewriting code in a more visible way can be better depending on the situation.

Well since I want to play with metalinks some more I created a simple Nautilus plugin that can show MetaLinks associated with a method... 
<2015-09-10_22:32:50.png>

But I don't know how useful it would be for real metalink usage... maybe I can publish it somewhere...

yes, this is a nice start to experiment! 

Marcus