Observing changes of regular attributes
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
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
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 <stepharo@free.fr> 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
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 <stepharo@free.fr <mailto:stepharo@free.fr>> 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
On 09 Sep 2015, at 21:26, Thierry Goubier <thierry.goubier@gmail.com> 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
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 <i.uhnak@gmail.com> 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
On Wed, Sep 9, 2015 at 10:04 PM, Marcus Denker <marcus.denker@inria.fr> 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
On 10 Sep 2015, at 19:45, Peter Uhnák <i.uhnak@gmail.com> wrote:
On Wed, Sep 9, 2015 at 10:04 PM, Marcus Denker <marcus.denker@inria.fr <mailto:marcus.denker@inria.fr>> 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
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
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
participants (5)
-
Marcus Denker -
Mariano Martinez Peck -
Peter Uhnák -
stepharo -
Thierry Goubier