Another way to go is just to do this: -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= ProtoObject subclass: #MyProxy instanceVariableNames: 'object' classVariableNames: '' category: â' MyProxy >> initialize object := self MyProxy >> doesNotUnderstand: aMessage ^ object perform: aMessage selector withArguments: aMessage arguments Object >> wrap self become: MyProxy new Object >> isProxy ^ false MyProxy >> isProxy ^ true -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= So the idea is that the reference to self in MyProxy becomes the wrapped object using the become. The main problem of this kind of implementation is that self is bounded to the proxy, so all the internal calls of self are not going to be intercepted and the return self is going to expose the original object. |obj| obj := Object new. obj isProxy. âfalse" obj wrap. obj isProxy. âtrueâ obj yourself isProxy âfalseâ <ââ This one kind of break the proxy Cheers, Alejandro
On Feb 27, 2015, at 9:35 AM, Camille <camille.teruel@gmail.com> wrote:
On 27 Feb 2015, at 03:43, Alexandre Bergel <alexandre.bergel@me.com> wrote:
Hi!
I have a near-to-be naive question. Maybe there is something obvious, but I cannot see it. Consider the following implementation of a proxy:
-=-=-=-=-=-=-=-=-=-=-=-= Object subclass: #MyProxy instanceVariableNames: 'object'.
MyProxy >> object: anObject object := anObject
MyProxy >> doesNotUnderstand: aMessage ^ object perform: aMessage selector withArguments: aMessage arguments
Object >> wrap self becomeForward: (MyProxy new object: self; yourself) -=-=-=-=-=-=-=-=-=-=-=-=
The problem is with wrap. After the becomeForward:, MyProxy has itself in the object variable. Even self is apparently subject to the #become.
It means that the following code loop indefinitely
-=-=-=-=-=-=-=-=-=-=-=-= d := Dictionary new. d wrap. d add: #foo -> 10 -=-=-=-=-=-=-=-=-=-=-=-=
I know there is Marianoâs library to write proxy. But I still wondering whether this could be done simply. Any idea how to simply create a proxy?
Hi Alexandre,
You have to store the target and the proxy in different temps, do the become and (re)set the link between both after. Or in your case, something like:
Object >> wrap | proxyThenTarget | proxyThenTarget := MyProxy new. self become: proxyThenTarget. âNow self is the proxy" self object: proxyThenTarget. ^ self
Note that by subclassing Object many messages wonât be intercepted. With your dictionary example it means that you cannot intercept #at: . Subclassing ProtoObject reduces the number of such messages. Also one can bypass these methods by sending #doesNotUndestand: to the proxy. In the end all depends on your requirements: do you care about uniformity (all messages must be intercepted), composition of proxies, security (no target leaks, no interception bypass), what operations do you want to intercept (just message sends or iv accesses in addition), etc... For most cases Ghost is the way to go.
Camille
Cheers, Alexandre
-- _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;: Alexandre Bergel http://www.bergel.eu <http://www.bergel.eu/> ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.