[Ann] New version of Ghost

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

[Ann] New version of Ghost

Denis Kudriashov
Hello.

I finished new version of Ghost:
  • DNU approach for basic proxies instead of #cannotInterpret: trick (trick used only for class proxies)
  • Abstract proxy classes uses Ghost name instead of Proxy: there are GHObjectGhost and GHClassGhost.
  • GHProxyHandler renamed to GHGhostBehaviour. Concrete ghosts should implement #ghostBehaviour instead of #proxyHandler.
  • GHGhostBehaviour should define #currentMetaLevel to specify set of messages which should not be intercepted. Such meta messages will be executed under ghost instance by subclass of GHMetaMessages.
In previous version there was dictionary which maps meta message selector to implementation selector. It was not suitable. Now meta messages should be directly implemented on particular GHMetaMessages subclass and all it methods are considered meta.
So GhostBehaviour should return instance of GHMetaLevel with meta messages implementation class:
    • GHMetaLevel with: GHEmptyMetaMessages "when all possible messages should intercepted"
    • GHMetaLevel with: GHStandartMetaMessages "when tools specific messages should not be intercepted"
For example standard meta messages implements #inspect:

GHStandartMetaMessages>>inspect
"Create and schedule an Inspector in which the user can examine the receiver's variables."
^ Smalltalk tools inspector inspect: ghost

  • Traits for methods explicitly defined on ghosts: TMinimalProxy, TNotNilProxy, TIdentifiedProxy (with #=, #hash, #class). Concrete proxies can add this traits to itself independently from meta level. For example traits supply convenient methods to retrieve ghost information in polymorphic way with objects:
    • ghost isGhost
    • ghost ghostClass "returns actual class of receiver"
    • ghost ghostPrintString "returns string which represents ghost from meta level point of view"
This traits are suitable and they provide some kind of optimisation for proxies (methods from traits are executed directly instead of complex meta messages mechanizm). But maybe they are superfluous. For example they can't be reused for class proxies which substitute real object classes (to intercept all instance messages).
  • GHClassGhost able to replace class of real objects. It implements cannotInterpret: trick to intercept all instance messages. Subclasses should define two behaviours: #ghostBehaviour (as any other ghost) and #instancesBehaviour which will process instance messages. In previous version it was different message to same #ghostBehaviour.
  • New kind of proxies:
    • GHObjectVirus. It is special kind of GHClassProxy. It infects real object to intercept it messages. From meta level infected object looks like healthy object which means that meta messages are executed by infected object itself. As class virus looks like real victim class. So in case when virus is created with standard meta level tools will not differ him from health object. There are special messages which allow ask object about viruses:
      • infectedObject isInfectedByVirus
      • infectedObject virus
      • infectedObject recoverFromVirus
    • GHLearningObject. It is suitable proxy which retrieves all unknown methods from teacher class. Thank's Stephan for this idea.
This kind of proxy allows me easily find required set of messages to support inspectors and debuggers. You can create instance of learning object by:
GHLearningObject withTeacher: Object.
And any operation with it will fill studiedMessages dictionary. In my case I opened GTInspector on it and got all messages which was needed for him. 
  • Ghosts works correctly with latest Pharo 5 tools (basic inspector, GTInspector, SpecDebugger, GTDebugger). Required methods for tools are extracted to 'Ghost-GTSupport' package. 
  • Repackaging:
    • Ghost-ObjectProxies. It contains all core classes and abstract GHObjectGhost which is based on DNU
    • Ghost-ClassProxies. It contains code for proxy which can substitute class of real object. GHClassGhost implements cannotInterpret: trick to intercept all instance messages. And it implement support for debugging such methods.
    • Ghost-LearningObject
    • Ghost-ObjectVirus
    • Ghost-GTSupport
    • test packages
  • All code moved to Pharo repository http://smalltalkhub.com/#!/~Pharo/Ghost (in includes packages from CAR repo too) 

You can load new version by:

Gofer it
smalltalkhubUser: 'Pharo' project: 'Ghost';
configurationOf: 'Ghost';
loadStable

I use it now in Seamless and Mocketry.


Reply | Threaded
Open this post in threaded view
|

Re: [Ann] New version of Ghost

philippeback
Awesome. Things are looking good.

Now, just have to find time to use all of this :-)

Phil

On Thu, Mar 24, 2016 at 5:48 PM, Denis Kudriashov <[hidden email]> wrote:
Hello.

I finished new version of Ghost:
  • DNU approach for basic proxies instead of #cannotInterpret: trick (trick used only for class proxies)
  • Abstract proxy classes uses Ghost name instead of Proxy: there are GHObjectGhost and GHClassGhost.
  • GHProxyHandler renamed to GHGhostBehaviour. Concrete ghosts should implement #ghostBehaviour instead of #proxyHandler.
  • GHGhostBehaviour should define #currentMetaLevel to specify set of messages which should not be intercepted. Such meta messages will be executed under ghost instance by subclass of GHMetaMessages.
In previous version there was dictionary which maps meta message selector to implementation selector. It was not suitable. Now meta messages should be directly implemented on particular GHMetaMessages subclass and all it methods are considered meta.
So GhostBehaviour should return instance of GHMetaLevel with meta messages implementation class:
    • GHMetaLevel with: GHEmptyMetaMessages "when all possible messages should intercepted"
    • GHMetaLevel with: GHStandartMetaMessages "when tools specific messages should not be intercepted"
For example standard meta messages implements #inspect:

GHStandartMetaMessages>>inspect
"Create and schedule an Inspector in which the user can examine the receiver's variables."
^ Smalltalk tools inspector inspect: ghost

  • Traits for methods explicitly defined on ghosts: TMinimalProxy, TNotNilProxy, TIdentifiedProxy (with #=, #hash, #class). Concrete proxies can add this traits to itself independently from meta level. For example traits supply convenient methods to retrieve ghost information in polymorphic way with objects:
    • ghost isGhost
    • ghost ghostClass "returns actual class of receiver"
    • ghost ghostPrintString "returns string which represents ghost from meta level point of view"
This traits are suitable and they provide some kind of optimisation for proxies (methods from traits are executed directly instead of complex meta messages mechanizm). But maybe they are superfluous. For example they can't be reused for class proxies which substitute real object classes (to intercept all instance messages).
  • GHClassGhost able to replace class of real objects. It implements cannotInterpret: trick to intercept all instance messages. Subclasses should define two behaviours: #ghostBehaviour (as any other ghost) and #instancesBehaviour which will process instance messages. In previous version it was different message to same #ghostBehaviour.
  • New kind of proxies:
    • GHObjectVirus. It is special kind of GHClassProxy. It infects real object to intercept it messages. From meta level infected object looks like healthy object which means that meta messages are executed by infected object itself. As class virus looks like real victim class. So in case when virus is created with standard meta level tools will not differ him from health object. There are special messages which allow ask object about viruses:
      • infectedObject isInfectedByVirus
      • infectedObject virus
      • infectedObject recoverFromVirus
    • GHLearningObject. It is suitable proxy which retrieves all unknown methods from teacher class. Thank's Stephan for this idea.
This kind of proxy allows me easily find required set of messages to support inspectors and debuggers. You can create instance of learning object by:
GHLearningObject withTeacher: Object.
And any operation with it will fill studiedMessages dictionary. In my case I opened GTInspector on it and got all messages which was needed for him. 
  • Ghosts works correctly with latest Pharo 5 tools (basic inspector, GTInspector, SpecDebugger, GTDebugger). Required methods for tools are extracted to 'Ghost-GTSupport' package. 
  • Repackaging:
    • Ghost-ObjectProxies. It contains all core classes and abstract GHObjectGhost which is based on DNU
    • Ghost-ClassProxies. It contains code for proxy which can substitute class of real object. GHClassGhost implements cannotInterpret: trick to intercept all instance messages. And it implement support for debugging such methods.
    • Ghost-LearningObject
    • Ghost-ObjectVirus
    • Ghost-GTSupport
    • test packages
  • All code moved to Pharo repository http://smalltalkhub.com/#!/~Pharo/Ghost (in includes packages from CAR repo too) 

You can load new version by:

Gofer it
smalltalkhubUser: 'Pharo' project: 'Ghost';
configurationOf: 'Ghost';
loadStable

I use it now in Seamless and Mocketry.



Reply | Threaded
Open this post in threaded view
|

Re: [Ann] New version of Ghost

Mariano Martinez Peck
In reply to this post by Denis Kudriashov


On Thu, Mar 24, 2016 at 1:48 PM, Denis Kudriashov <[hidden email]> wrote:
Hello.

I finished new version of Ghost:


That's very nice to hear!! I love to see someone took it and improve it :)
 
  • DNU approach for basic proxies instead of #cannotInterpret: trick (trick used only for class proxies)
Excellent. Yes, I remember the discussion we had weeks ago. 
  • Abstract proxy classes uses Ghost name instead of Proxy: there are GHObjectGhost and GHClassGhost.
  • GHProxyHandler renamed to GHGhostBehaviour. Concrete ghosts should implement #ghostBehaviour instead of #proxyHandler.
  • GHGhostBehaviour should define #currentMetaLevel to specify set of messages which should not be intercepted. Such meta messages will be executed under ghost instance by subclass of GHMetaMessages.
In previous version there was dictionary which maps meta message selector to implementation selector. It was not suitable. Now meta messages should be directly implemented on particular GHMetaMessages subclass and all it methods are considered meta.
So GhostBehaviour should return instance of GHMetaLevel with meta messages implementation class:
    • GHMetaLevel with: GHEmptyMetaMessages "when all possible messages should intercepted"
    • GHMetaLevel with: GHStandartMetaMessages "when tools specific messages should not be intercepted"
For example standard meta messages implements #inspect:

GHStandartMetaMessages>>inspect
"Create and schedule an Inspector in which the user can examine the receiver's variables."
^ Smalltalk tools inspector inspect: ghost



Nice. Yes, this is much better than my original dictionary-based solution 
 
  • Traits for methods explicitly defined on ghosts: TMinimalProxy, TNotNilProxy, TIdentifiedProxy (with #=, #hash, #class). Concrete proxies can add this traits to itself independently from meta level. For example traits supply convenient methods to retrieve ghost information in polymorphic way with objects:
    • ghost isGhost
    • ghost ghostClass "returns actual class of receiver"
    • ghost ghostPrintString "returns string which represents ghost from meta level point of view"
This traits are suitable and they provide some kind of optimisation for proxies (methods from traits are executed directly instead of complex meta messages mechanizm). But maybe they are superfluous. For example they can't be reused for class proxies which substitute real object classes (to intercept all instance messages).


Good idea as well. Just as yet another useful example of this, I recommend watching the proxies I defined for Marea as you will have interesting proxies for classes and metaclasses. Basically, I defined quite some methods in those proxies so that to avoid intercepting and faulting my objects. See Marea code and watch for it's proxies! Let me know if you found the methods I am talking about. 
 
  • GHClassGhost able to replace class of real objects. It implements cannotInterpret: trick to intercept all instance messages. Subclasses should define two behaviours: #ghostBehaviour (as any other ghost) and #instancesBehaviour which will process instance messages. In previous version it was different message to same #ghostBehaviour.
  • New kind of proxies:
    • GHObjectVirus. It is special kind of GHClassProxy. It infects real object to intercept it messages. From meta level infected object looks like healthy object which means that meta messages are executed by infected object itself. As class virus looks like real victim class. So in case when virus is created with standard meta level tools will not differ him from health object. There are special messages which allow ask object about viruses:
      • infectedObject isInfectedByVirus
      • infectedObject virus
      • infectedObject recoverFromVirus

Sorry I did not get this one. 
 
    • GHLearningObject. It is suitable proxy which retrieves all unknown methods from teacher class. Thank's Stephan for this idea.
This kind of proxy allows me easily find required set of messages to support inspectors and debuggers. You can create instance of learning object by:
GHLearningObject withTeacher: Object.
And any operation with it will fill studiedMessages dictionary. In my case I opened GTInspector on it and got all messages which was needed for him. 

Great idea too. I had to come with the set of mapped selectors (the dictionary) by poor man human try and error hahaha. 
 
  • Ghosts works correctly with latest Pharo 5 tools (basic inspector, GTInspector, SpecDebugger, GTDebugger). Required methods for tools are extracted to 'Ghost-GTSupport' package. 
  • Repackaging:
    • Ghost-ObjectProxies. It contains all core classes and abstract GHObjectGhost which is based on DNU
    • Ghost-ClassProxies. It contains code for proxy which can substitute class of real object. GHClassGhost implements cannotInterpret: trick to intercept all instance messages. And it implement support for debugging such methods.
    • Ghost-LearningObject
    • Ghost-ObjectVirus
    • Ghost-GTSupport
    • test packages
  • All code moved to Pharo repository http://smalltalkhub.com/#!/~Pharo/Ghost (in includes packages from CAR repo too) 


Excellent. 

 
Thanks Denis for pushing Ghost further!


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

Re: [Ann] New version of Ghost

Denis Kudriashov
Hi.
Thank's for kind words.

2016-03-24 19:22 GMT+01:00 Mariano Martinez Peck <[hidden email]>:
  • GHClassGhost able to replace class of real objects. It implements cannotInterpret: trick to intercept all instance messages. Subclasses should define two behaviours: #ghostBehaviour (as any other ghost) and #instancesBehaviour which will process instance messages. In previous version it was different message to same #ghostBehaviour.

In your original version you implemented #cannotInterpert: for instance messages such way:
proxy proxyHandler handleInterceptionToInstance: interception.
And proxy handler was responsible for two messages: #handleInterceptionToInstance: and #handleInterception:. 
In my version I ask proxy for different kind of handler (ghostBehaviour):

GHObjectGhost>>doesNotUnderstand: aMessage
self ghostBehaviour intercept: aMessage to: self

GHInstanceMessagesInterceptor>>cannotInterpret: aMessage
"some logic to find ghostClass"
ghostClass instancesBehaviour intercept: aMessage to: self
 
  • New kind of proxies:
    • GHObjectVirus. It is special kind of GHClassProxy. It infects real object to intercept it messages. From meta level infected object looks like healthy object which means that meta messages are executed by infected object itself. As class virus looks like real victim class. So in case when virus is created with standard meta level tools will not differ him from health object. There are special messages which allow ask object about viruses:
      • infectedObject isInfectedByVirus
      • infectedObject virus
      • infectedObject recoverFromVirus

Sorry I did not get this one. 

Good example where I use viruses is stubbing real objects in Mocketry. I will announce it soon. You can do this:
rect := 0@0 corner: 2@3
rect stub area willReturn: 1000.

rect area "=> 1000".
rect origin "=> 0@0".

From any tool you will see normal rectangle. Nothing special. But in reality it is infected by virus which delegate all messages to "Mocketry machinery". And you can detect it by:
rect isInfectedByVirus "=> true"
And you can heal infected object:
rect recoverFromVirus. "or virus heal: infectedObject"
rect isInfectedByVirus "=> false"

Reply | Threaded
Open this post in threaded view
|

Re: [Ann] New version of Ghost

stepharo
In reply to this post by Denis Kudriashov


Le 24/3/16 17:48, Denis Kudriashov a écrit :
Hello.

I finished new version of Ghost:
  • DNU approach for basic proxies instead of #cannotInterpret: trick (trick used only for class proxies)
Does it mean that we cannot proxy classes?

  • Abstract proxy classes uses Ghost name instead of Proxy: there are GHObjectGhost and GHClassGhost.
  • GHProxyHandler renamed to GHGhostBehaviour. Concrete ghosts should implement #ghostBehaviour instead of #proxyHandler.
  • GHGhostBehaviour should define #currentMetaLevel to specify set of messages which should not be intercepted. Such meta messages will be executed under ghost instance by subclass of GHMetaMessages.
In previous version there was dictionary which maps meta message selector to implementation selector. It was not suitable. Now meta messages should be directly implemented on particular GHMetaMessages subclass and all it methods are considered meta.
So GhostBehaviour should return instance of GHMetaLevel with meta messages implementation class:
    • GHMetaLevel with: GHEmptyMetaMessages "when all possible messages should intercepted"
    • GHMetaLevel with: GHStandartMetaMessages "when tools specific messages should not be intercepted"
For example standard meta messages implements #inspect:

GHStandartMetaMessages>>inspect
"Create and schedule an Inspector in which the user can examine the receiver's variables."
^ Smalltalk tools inspector inspect: ghost

  • Traits for methods explicitly defined on ghosts: TMinimalProxy, TNotNilProxy, TIdentifiedProxy (with #=, #hash, #class). Concrete proxies can add this traits to itself independently from meta level. For example traits supply convenient methods to retrieve ghost information in polymorphic way with objects:
    • ghost isGhost
    • ghost ghostClass "returns actual class of receiver"
    • ghost ghostPrintString "returns string which represents ghost from meta level point of view"
This traits are suitable and they provide some kind of optimisation for proxies (methods from traits are executed directly instead of complex meta messages mechanizm). But maybe they are superfluous. For example they can't be reused for class proxies which substitute real object classes (to intercept all instance messages).
  • GHClassGhost able to replace class of real objects. It implements cannotInterpret: trick to intercept all instance messages. Subclasses should define two behaviours: #ghostBehaviour (as any other ghost) and #instancesBehaviour which will process instance messages. In previous version it was different message to same #ghostBehaviour.
  • New kind of proxies:
    • GHObjectVirus. It is special kind of GHClassProxy. It infects real object to intercept it messages. From meta level infected object looks like healthy object which means that meta messages are executed by infected object itself. As class virus looks like real victim class. So in case when virus is created with standard meta level tools will not differ him from health object. There are special messages which allow ask object about viruses:
      • infectedObject isInfectedByVirus
      • infectedObject virus
      • infectedObject recoverFromVirus
    • GHLearningObject. It is suitable proxy which retrieves all unknown methods from teacher class. Thank's Stephan for this idea.
This kind of proxy allows me easily find required set of messages to support inspectors and debuggers. You can create instance of learning object by:
GHLearningObject withTeacher: Object.
And any operation with it will fill studiedMessages dictionary. In my case I opened GTInspector on it and got all messages which was needed for him. 
  • Ghosts works correctly with latest Pharo 5 tools (basic inspector, GTInspector, SpecDebugger, GTDebugger). Required methods for tools are extracted to 'Ghost-GTSupport' package. 
  • Repackaging:
    • Ghost-ObjectProxies. It contains all core classes and abstract GHObjectGhost which is based on DNU
    • Ghost-ClassProxies. It contains code for proxy which can substitute class of real object. GHClassGhost implements cannotInterpret: trick to intercept all instance messages. And it implement support for debugging such methods.
    • Ghost-LearningObject
    • Ghost-ObjectVirus
    • Ghost-GTSupport
    • test packages
  • All code moved to Pharo repository http://smalltalkhub.com/#!/~Pharo/Ghost (in includes packages from CAR repo too) 

You can load new version by:

Gofer it
smalltalkhubUser: 'Pharo' project: 'Ghost';
configurationOf: 'Ghost';
loadStable

I use it now in Seamless and Mocketry.



Reply | Threaded
Open this post in threaded view
|

Re: [Ann] New version of Ghost

stepharo
In reply to this post by Denis Kudriashov


Le 24/3/16 17:48, Denis Kudriashov a écrit :
Hello.

I finished new version of Ghost:
  • DNU approach for basic proxies instead of #cannotInterpret: trick (trick used only for class proxies)
  • Abstract proxy classes uses Ghost name instead of Proxy: there are GHObjectGhost and GHClassGhost.
  • GHProxyHandler renamed to GHGhostBehaviour. Concrete ghosts should implement #ghostBehaviour instead of #proxyHandler.
  • GHGhostBehaviour should define #currentMetaLevel to specify set of messages which should not be intercepted. Such meta messages will be executed under ghost instance by subclass of GHMetaMessages.
In previous version there was dictionary which maps meta message selector to implementation selector. It was not suitable. Now meta messages should be directly implemented on particular GHMetaMessages subclass and all it methods are considered meta.
So GhostBehaviour should return instance of GHMetaLevel with meta messages implementation class:

Do you mean that you use subclasses to register selectors that will not be trapped?
Why is is better than a collection on the object?
    • GHMetaLevel with: GHEmptyMetaMessages "when all possible messages should intercepted"
    • GHMetaLevel with: GHStandartMetaMessages "when tools specific messages should not be intercepted"
For example standard meta messages implements #inspect:

    Pay attention Standard and no Standart
GHStandartMetaMessages>>inspect
"Create and schedule an Inspector in which the user can examine the receiver's variables."
^ Smalltalk tools inspector inspect: ghost

  • Traits for methods explicitly defined on ghosts: TMinimalProxy, TNotNilProxy, TIdentifiedProxy (with #=, #hash, #class). Concrete proxies can add this traits to itself independently from meta level. For example traits supply convenient methods to retrieve ghost information in polymorphic way with objects:
    • ghost isGhost
    • ghost ghostClass "returns actual class of receiver"
                when I read ghostClass I expect getting the class implementing the proxy not the proxied class.
                So I'm confused.

    • ghost ghostPrintString "returns string which represents ghost from meta level point of view"
This traits are suitable and they provide some kind of optimisation for proxies (methods from traits are executed directly instead of complex meta messages mechanizm). But maybe they are superfluous. For example they can't be reused for class proxies which substitute real object classes (to intercept all instance messages).
  • GHClassGhost able to replace class of real objects. It implements cannotInterpret: trick to intercept all instance messages. Subclasses should define two behaviours: #ghostBehaviour (as any other ghost) and #instancesBehaviour which will process instance messages. In previous version it was different message to same #ghostBehaviour.
  • New kind of proxies:
    • GHObjectVirus. It is special kind of GHClassProxy. It infects real object to intercept it messages. From meta level infected object looks like healthy object which means that meta messages are executed by infected object itself. As class virus looks like real victim class. So in case when virus is created with standard meta level tools will not differ him from health object. There are special messages which allow ask object about viruses:
      • infectedObject isInfectedByVirus
      • infectedObject virus
      • infectedObject recoverFromVirus
                        I could not understand what is a Virus.

    • GHLearningObject. It is suitable proxy which retrieves all unknown methods from teacher class. Thank's Stephan for this idea.
This kind of proxy allows me easily find required set of messages to support inspectors and debuggers. You can create instance of learning object by:
GHLearningObject withTeacher: Object.
And any operation with it will fill studiedMessages dictionary. In my case I opened GTInspector on it and got all messages which was needed for him.
                    :)
  • Ghosts works correctly with latest Pharo 5 tools (basic inspector, GTInspector, SpecDebugger, GTDebugger). Required methods for tools are extracted to 'Ghost-GTSupport' package. 
  • Repackaging:
    • Ghost-ObjectProxies. It contains all core classes and abstract GHObjectGhost which is based on DNU
    • Ghost-ClassProxies. It contains code for proxy which can substitute class of real object. GHClassGhost implements cannotInterpret: trick to intercept all instance messages. And it implement support for debugging such methods.
    • Ghost-LearningObject
    • Ghost-ObjectVirus
    • Ghost-GTSupport
    • test packages
  • All code moved to Pharo repository http://smalltalkhub.com/#!/~Pharo/Ghost (in includes packages from CAR repo too) 

Denis it would be good to have some examples described.


You can load new version by:

Gofer it
smalltalkhubUser: 'Pharo' project: 'Ghost';
configurationOf: 'Ghost';
loadStable

I use it now in Seamless and Mocketry.



Reply | Threaded
Open this post in threaded view
|

Re: [Ann] New version of Ghost

Denis Kudriashov
In reply to this post by philippeback

2016-03-24 19:15 GMT+01:00 [hidden email] <[hidden email]>:
Awesome. Things are looking good.

Now, just have to find time to use all of this :-)

I just should say that I am not succeed to provide really safe ghosts. 
If you will try to implement new kind of proxy (on top of Ghost) it is possible to hang image. 
Problem that when you make some mistake in implementation it usually lead to infinite recursion and interrupt usually not helps because opened debugger produces new messages to ghost which produces another recursion due to original errors. And errors are not only exceptions but some unexpected messages to proxies. For example if you will use Set to implement proxy behaviour (for some reason) it will send #= and #hash to proxy when you will try to add it.
There are tools now to minimize such cases. For example standart meta level will not intercept messages from debugger. But as soon as you start experiment with empty meta level you will  get such problems.
This week Guille Polito start to use Ghost for new proxies and he was not happy due to this kind of problems. Maybe together we will find some solution how to make ghosts safe.  

Reply | Threaded
Open this post in threaded view
|

Re: [Ann] New version of Ghost

Denis Kudriashov
In reply to this post by stepharo

2016-03-24 20:18 GMT+01:00 stepharo <[hidden email]>:
Does it mean that we cannot proxy classes?

For this purpose there is GHClassGhost. I wrote about it in response to Mariano
Reply | Threaded
Open this post in threaded view
|

Re: [Ann] New version of Ghost

Denis Kudriashov
In reply to this post by stepharo

2016-03-24 20:27 GMT+01:00 stepharo <[hidden email]>:
Pay attention Standard and no Standart

So what the right word? Standart exists in my english dictionary
Reply | Threaded
Open this post in threaded view
|

Re: [Ann] New version of Ghost

Denis Kudriashov
In reply to this post by stepharo

2016-03-24 20:27 GMT+01:00 stepharo <[hidden email]>:
Do you mean that you use subclasses to register selectors that will not be trapped? 
Why is is better than a collection on the object?

I not understand your question.
For example you want to make message #asString meta. You can implement it directly in class GHStandartMetaMessages:
GHStandartMetaMessages>>asString
"here there is instance variable ghost which you can use for implementation"
^'string presentation for ghost'

Now if you will define your proxy with standart meta level #asString will be not intercepted and instead GHStandartMetaMessages>>asString will be executed with ghost. 

In previous version you would add #asString to special map:
initializeMetaLevel
"many many other mappings here and new one"
notInterceptedMessages at: #asString put: #handleAsStringFor:


Reply | Threaded
Open this post in threaded view
|

Re: [Ann] New version of Ghost

Denis Kudriashov
In reply to this post by Mariano Martinez Peck

2016-03-24 19:22 GMT+01:00 Mariano Martinez Peck <[hidden email]>:
Good idea as well. Just as yet another useful example of this, I recommend watching the proxies I defined for Marea as you will have interesting proxies for classes and metaclasses. Basically, I defined quite some methods in those proxies so that to avoid intercepting and faulting my objects. See Marea code and watch for it's proxies! Let me know if you found the methods I am talking about. 

And where is code? Of course I want to look
Reply | Threaded
Open this post in threaded view
|

Re: [Ann] New version of Ghost

Damien Pollet
In reply to this post by Denis Kudriashov
On 24 March 2016 at 20:38, Denis Kudriashov <[hidden email]> wrote:

2016-03-24 20:27 GMT+01:00 stepharo <[hidden email]>:
Pay attention Standard and no Standart

So what the right word? Standart exists in my english dictionary

Standard with a D is correct; only version found in my copy of the Oxford English Dictionary.

Standart with a T is a proper name, according to wikipedia https://en.wikipedia.org/wiki/Standart

--
Damien Pollet
type less, do more [ | ] http://people.untyped.org/damien.pollet
Reply | Threaded
Open this post in threaded view
|

Re: [Ann] New version of Ghost

Denis Kudriashov

2016-03-24 23:26 GMT+01:00 Damien Pollet <[hidden email]>:
Standard with a D is correct; only version found in my copy of the Oxford English Dictionary.

Standart with a T is a proper name, according to wikipedia https://en.wikipedia.org/wiki/Standart

Interesting. I will rename it
Reply | Threaded
Open this post in threaded view
|

Re: [Ann] New version of Ghost

Mariano Martinez Peck
In reply to this post by Denis Kudriashov


On Thu, Mar 24, 2016 at 4:02 PM, Denis Kudriashov <[hidden email]> wrote:
Hi.
Thank's for kind words.

2016-03-24 19:22 GMT+01:00 Mariano Martinez Peck <[hidden email]>:
  • GHClassGhost able to replace class of real objects. It implements cannotInterpret: trick to intercept all instance messages. Subclasses should define two behaviours: #ghostBehaviour (as any other ghost) and #instancesBehaviour which will process instance messages. In previous version it was different message to same #ghostBehaviour.

In your original version you implemented #cannotInterpert: for instance messages such way:
proxy proxyHandler handleInterceptionToInstance: interception.
And proxy handler was responsible for two messages: #handleInterceptionToInstance: and #handleInterception:. 
In my version I ask proxy for different kind of handler (ghostBehaviour):

GHObjectGhost>>doesNotUnderstand: aMessage
self ghostBehaviour intercept: aMessage to: self

GHInstanceMessagesInterceptor>>cannotInterpret: aMessage
"some logic to find ghostClass"
ghostClass instancesBehaviour intercept: aMessage to: self
 


OK, that's good. I like it.

 
  • New kind of proxies:
    • GHObjectVirus. It is special kind of GHClassProxy. It infects real object to intercept it messages. From meta level infected object looks like healthy object which means that meta messages are executed by infected object itself. As class virus looks like real victim class. So in case when virus is created with standard meta level tools will not differ him from health object. There are special messages which allow ask object about viruses:
      • infectedObject isInfectedByVirus
      • infectedObject virus
      • infectedObject recoverFromVirus

Sorry I did not get this one. 

Good example where I use viruses is stubbing real objects in Mocketry. I will announce it soon. You can do this:
rect := 0@0 corner: 2@3
rect stub area willReturn: 1000.

rect area "=> 1000".
rect origin "=> 0@0".


OK..I should take a look to the code...but...it looks to me that stub the only thing it does is to create the proxy and then the #become: ??


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

Re: [Ann] New version of Ghost

Mariano Martinez Peck
In reply to this post by Denis Kudriashov


On Thu, Mar 24, 2016 at 4:33 PM, Denis Kudriashov <[hidden email]> wrote:

2016-03-24 19:15 GMT+01:00 [hidden email] <[hidden email]>:
Awesome. Things are looking good.

Now, just have to find time to use all of this :-)

I just should say that I am not succeed to provide really safe ghosts. 
If you will try to implement new kind of proxy (on top of Ghost) it is possible to hang image. 
Problem that when you make some mistake in implementation it usually lead to infinite recursion and interrupt usually not helps because opened debugger produces new messages to ghost which produces another recursion due to original errors. And errors are not only exceptions but some unexpected messages to proxies. For example if you will use Set to implement proxy behaviour (for some reason) it will send #= and #hash to proxy when you will try to add it.

Exactly. That's why Marea had to extend Fuel because otherwise, when I was serializing a graph that contained proxies, the Fuel message sends to the proxy would be intercepted and cause the swap in! hahahah. Therefore, in Marea I extend Fuel to use a custom dictionary and a custom cluster for proxies :)

Ohh that's another interesting example that would be nice to be added to this new Ghost. 
 
There are tools now to minimize such cases. For example standart meta level will not intercept messages from debugger. But as soon as you start experiment with empty meta level you will  get such problems.
This week Guille Polito start to use Ghost for new proxies and he was not happy due to this kind of problems. Maybe together we will find some solution how to make ghosts safe.  




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

Re: [Ann] New version of Ghost

Mariano Martinez Peck
In reply to this post by Denis Kudriashov


On Thu, Mar 24, 2016 at 4:52 PM, Denis Kudriashov <[hidden email]> wrote:

2016-03-24 19:22 GMT+01:00 Mariano Martinez Peck <[hidden email]>:
Good idea as well. Just as yet another useful example of this, I recommend watching the proxies I defined for Marea as you will have interesting proxies for classes and metaclasses. Basically, I defined quite some methods in those proxies so that to avoid intercepting and faulting my objects. See Marea code and watch for it's proxies! Let me know if you found the methods I am talking about. 

And where is code? Of course I want to look

The code is in http://ss3.gemstone.com/ss/Marea

BTW..note that last time I tried Marea was in Pharo 1.4 so.. not sure if it would load now. I have a one-click in either case that you can find here: https://www.dropbox.com/sh/xp8jzyypmz0898j/AACRdHno6V7UfhaJ1ofTPPXva?dl=0

And what you are looking is in category 'Marea-Proxies'. See for example MARClassProxy or MARMetaclassProxy as the examples were I added messages to the proxies to avoid being intercepted. Those methods allowed me the reduce the unncessary "swap in" when I had swapped out classes and instances and suddently a simple #do: over behaviors swapped everything in. 

In Marea you will find the IMPORTANT work for which I used Ghost approach. 

Cheers,

Reply | Threaded
Open this post in threaded view
|

Re: [Ann] New version of Ghost

demarey
In reply to this post by Denis Kudriashov
Good job Denis!

Le 24 mars 2016 à 17:48, Denis Kudriashov <[hidden email]> a écrit :

Hello.

I finished new version of Ghost:
  • Abstract proxy classes uses Ghost name instead of Proxy: there are GHObjectGhost and GHClassGhost.
  • GHProxyHandler renamed to GHGhostBehaviour. Concrete ghosts should implement #ghostBehaviour instead of #proxyHandler.
Why did you rename these classes?
I find the new names obscure and they do not provide a clue of what is the purpose of the class. Old names were clear and easily understandable.
  • New kind of proxies:
    • GHObjectVirus. It is special kind of GHClassProxy. It infects real object to intercept it messages. From meta level infected object looks like healthy object which means that meta messages are executed by infected object itself. As class virus looks like real victim 
Same remark here. The name is fun but it does not give any clue on the purpose of the class. Why not use GHMessageInterceptor?

Sorry to bother you but names are really important.
Christophe
Reply | Threaded
Open this post in threaded view
|

Re: [Ann] New version of Ghost

Mariano Martinez Peck


On Fri, Mar 25, 2016 at 5:47 AM, Christophe Demarey <[hidden email]> wrote:
Good job Denis!

Le 24 mars 2016 à 17:48, Denis Kudriashov <[hidden email]> a écrit :

Hello.

I finished new version of Ghost:
  • Abstract proxy classes uses Ghost name instead of Proxy: there are GHObjectGhost and GHClassGhost.
  • GHProxyHandler renamed to GHGhostBehaviour. Concrete ghosts should implement #ghostBehaviour instead of #proxyHandler.
Why did you rename these classes?
I find the new names obscure and they do not provide a clue of what is the purpose of the class. Old names were clear and easily understandable.


I agree here. I originally called the tool Ghost mostly because I wanted TRANSPARENT proxies for all kind of objects (included classes, methods, etc), and LIGHTWEIGHT.  So...I thought that Ghost were transparent and lightweight hahahaha. 

But... one thing is the project name and the other is class names. Here I agree with Christophe that I prefer the old names. Same as for the virus stuff. I would not go that deep into the metaphor. 



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

Re: [Ann] New version of Ghost

Denis Kudriashov
In reply to this post by demarey
Hi

2016-03-25 9:47 GMT+01:00 Christophe Demarey <[hidden email]>:
  • Abstract proxy classes uses Ghost name instead of Proxy: there are GHObjectGhost and GHClassGhost.
  • GHProxyHandler renamed to GHGhostBehaviour. Concrete ghosts should implement #ghostBehaviour instead of #proxyHandler.
Why did you rename these classes?
I find the new names obscure and they do not provide a clue of what is the purpose of the class. Old names were clear and easily understandable.

Nice you ask. It can raise interesting discussion.

In previous version we have three classes to support basic object proxy:
GHInterceptionDelegator
GHProxyTrap 
GHAbstractProxy 
And now due to DNU approach it just one:
GHObjectGhost

And I guess you would call it GHObjectProxy or GHAbstractProxy. Lets look at wikipedia:
 
proxy, in its most general form, is a class functioning as an interface to something else. The proxy could interface to anything: a network connection, a large object in memory, a file, or some other resource that is expensive or impossible to duplicate. In short, a proxy is a wrapper or agent object that is being called by the client to access the real serving object behind the scenes 
 
So proxy is supposed to substitute some other object. But in many cases we not have other object. In many cases we construct special kind of objects which perform messages in not smalltalk way. For example imaging that we want to implement javascript prototypes (there was related post https://clementbera.wordpress.com/2016/02/17/mind-twister-toying-with-object-kernels). Prototype is definitely not kind of proxy. Or think about Mock object. It is not proxy too.
So generally Ghost is not about proxies. It is exactly about supernatural objects. With Ghost we construct special objects which behave in not natural smalltalk way. 
And in that perspective classic proxy is most primitive example of it. It just delegates all messages to another object (with little bit of logic).

Maybe you would suggest another name: GHInterceptionDelegator (what the name for GHGhostClass in that case?). 
But why we not call Object same way too (InterceptionDelegator)? Natural smalltalk objects just delegate message processing to methods from class methodDictionary (which is hidden by VM). 

So for me ObjectGhost reflects perfectly real intention of it. It is base class to construct unnatural smalltalk objects. And ClassGhost is unnatural object which can play role of natural object classes.

Now lets look at ProxyHandler vs GhostBehaviour. ProxyHandler play role of Behavior (Class) but for proxies. It defines how proxies will handle messages. But why we not call smalltalk Behaviour as ObjectHandler?
I hope now you see logic behind my names and ghost metaphor. Ghost models special objects with similar terms from natural objects: Object -> ObjectGhost and Behavior -> GhostBehaviour.

I changed title of Ghost project to: 
Ghost is framework to implement unnatural smalltalk objects like proxies and prototypes.,
  • New kind of proxies:
    • GHObjectVirus. It is special kind of GHClassProxy. It infects real object to intercept it messages. From meta level infected object looks like healthy object which means that meta messages are executed by infected object itself. As class virus looks like real victim 
Same remark here. The name is fun but it does not give any clue on the purpose of the class. Why not use GHMessageInterceptor?

And following such approach we will have GHInterceptionDelegator (for objects) and GHMessageInterceptor (for classes). Is it good?
I will describe virus more detailed soon. But maybe you remember there was very old advice from famous books: don't create classes which ends with -ER or -OR. (I not found original source but google shows many followers 


Sorry to bother you but names are really important.

Exactly!!! 


Reply | Threaded
Open this post in threaded view
|

Re: [Ann] New version of Ghost

Denis Kudriashov
In reply to this post by Mariano Martinez Peck

2016-03-25 13:26 GMT+01:00 Mariano Martinez Peck <[hidden email]>:
I agree here. I originally called the tool Ghost mostly because I wanted TRANSPARENT proxies for all kind of objects (included classes, methods, etc), and LIGHTWEIGHT.  So...I thought that Ghost were transparent and lightweight hahahaha. 

But I realised real value of this metaphor (not just lightness). I answer to Christophe
12