Surely if you have a wrapper class which only holds a reference to a single object that has all of the data, and that has accessors, then the wrapper can only use the accessors? The data object could have a flag that causes all of the accessors to throw an exception when it is set.
Or am I missing something?
On 10/2/08, Randal L. Schwartz merlyn@stonehenge.com wrote:
"Sean" == Sean Allen sean@monkeysnatchbanana.com writes:
Sean> If you wanted to take a mutable object and make it immutable and be able Sean> to go back again to mutable, how could you do that?
Squeak doesn't have that sort of capability. The immutability of a few classes is because the VM recognizes them specially, and not available at the programmer level without modifying the VM.
Other Smalltalk VMs are different. I think both VisualWorks and GemStone/S have primitive bits on an object to be informed when a mutation might be attempted.
You can simulate that *mostly* in Squeak by using a "proxy" object that intercepts all messages and looks for the dangerous ones, but that's gonna be a bit hard to do, and won't be aware of any new code that might call the mutating primitives directly. (*Any* method can call a primitive.)
-- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 merlyn@stonehenge.com URL:http://www.stonehenge.com/merlyn/ Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion _______________________________________________ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
You'd have to specially code each accessor in that case to check the flag.
Ideally I'd like to be able to step in front of every message send to descendent objects and decide whether to pass along ( read call ) or reject ( write call ).
then, all the logic is in one place and the accessors don't need to know about what is going on.
any way to do that?
i'm ok with the primitive problem as i don't need real immutability. just 'application level' immutability... ideally, without special coding in every accessor method ( that would get tedious very quickly ).
On Oct 2, 2008, at 12:47 PM, Marcin Tustin wrote:
Surely if you have a wrapper class which only holds a reference to a single object that has all of the data, and that has accessors, then the wrapper can only use the accessors? The data object could have a flag that causes all of the accessors to throw an exception when it is set.
Or am I missing something?
On 10/2/08, Randal L. Schwartz merlyn@stonehenge.com wrote:
"Sean" == Sean Allen sean@monkeysnatchbanana.com writes:
Sean> If you wanted to take a mutable object and make it immutable and be able Sean> to go back again to mutable, how could you do that?
Squeak doesn't have that sort of capability. The immutability of a few classes is because the VM recognizes them specially, and not available at the programmer level without modifying the VM.
Other Smalltalk VMs are different. I think both VisualWorks and GemStone/S have primitive bits on an object to be informed when a mutation might be attempted.
You can simulate that *mostly* in Squeak by using a "proxy" object that intercepts all messages and looks for the dangerous ones, but that's gonna be a bit hard to do, and won't be aware of any new code that might call the mutating primitives directly. (*Any* method can call a primitive.)
-- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 merlyn@stonehenge.com URL:http://www.stonehenge.com/merlyn/ Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion _______________________________________________ Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
Beginners mailing list Beginners@lists.squeakfoundation.org http://lists.squeakfoundation.org/mailman/listinfo/beginners
Am 02.10.2008 um 10:17 schrieb Sean Allen:
You'd have to specially code each accessor in that case to check the flag.
Ideally I'd like to be able to step in front of every message send to descendent objects and decide whether to pass along ( read call ) or reject ( write call ).
then, all the logic is in one place and the accessors don't need to know about what is going on.
any way to do that?
The proxy Randal was suggesting can do that. It encapsulates an object, and decides wether to pass on messages or not.
i'm ok with the primitive problem as i don't need real immutability. just 'application level' immutability... ideally, without special coding in every accessor method ( that would get tedious very quickly ).
On Oct 2, 2008, at 12:47 PM, Marcin Tustin wrote:
Surely if you have a wrapper class which only holds a reference to a single object that has all of the data, and that has accessors, then the wrapper can only use the accessors? The data object could have a flag that causes all of the accessors to throw an exception when it is set.
Or am I missing something?
On 10/2/08, Randal L. Schwartz merlyn@stonehenge.com wrote: >>>>> "Sean" == Sean Allen sean@monkeysnatchbanana.com writes:
Sean> If you wanted to take a mutable object and make it immutable and be able Sean> to go back again to mutable, how could you do that?
Squeak doesn't have that sort of capability. The immutability of a few classes is because the VM recognizes them specially, and not available at the programmer level without modifying the VM.
Other Smalltalk VMs are different. I think both VisualWorks and GemStone/S have primitive bits on an object to be informed when a mutation might be attempted.
You can simulate that *mostly* in Squeak by using a "proxy" object that intercepts all messages and looks for the dangerous ones, but that's gonna be a bit hard to do, and won't be aware of any new code that might call the mutating primitives directly. (*Any* method can call a primitive.)
-- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 merlyn@stonehenge.com URL:http://www.stonehenge.com/merlyn/ Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion ______________________________________________
Ok, there are two options...
First, if the object needs to be inmutable, just doit without setters. Let it be updated at once, with only one message which updates the instance variables from an already valid object. This way you can ensure that the original object will only be updated when you want to. It's an 'Application level' inmutability.
The second option is the proxy one, with a collection of 'dangerous' messages that will throw an exception when sended. This can be easily done by defining only the doesNotUnderstand: method in the proxy to search for the message in the collection and if it's found, raise the exception, if not, resend it to the proxyed object.
"Marcin" == Marcin Tustin mm3@zepler.net writes:
Marcin> Surely if you have a wrapper class which only holds a reference to a Marcin> single object that has all of the data, and that has accessors, then Marcin> the wrapper can only use the accessors? The data object could have a Marcin> flag that causes all of the accessors to throw an exception when it is Marcin> set.
Well, if everyone using the object promises to play nice, sure.
But the debugger doesn't have any special privileges, and it can clearly access every inst var, regardless of whether accessors exist or not, through the magic of #instVarAt: and friends.
So code would merely have to execute the equivalent of the primitives behind #instVarAt: and #instVarAt:put:, and no amount of wrapper class would help.
If the problem is "how do I ensure this object *doesn't* get mutated?", this is not a complete solution, just a slow simulation as long as everyone cooperates.
Am 02.10.2008 um 10:26 schrieb Randal L. Schwartz:
But the debugger doesn't have any special privileges, and it can clearly access every inst var, regardless of whether accessors exist or not, through the magic of #instVarAt: and friends.
There is no magic in #instVarAt:. It exists merely for helping debugging.
So code would merely have to execute the equivalent of the primitives behind #instVarAt: and #instVarAt:put:, and no amount of wrapper class would help.
That is not correct. There are no primitives that modify/access *other* objects. That would break encapsulation.
All you need to do to prevent the debugger from accessing instance variables is overwriting the methods the debugger invokes.
- Bert -
"Bert" == Bert Freudenberg bert@freudenbergs.de writes:
Bert> There is no magic in #instVarAt:. It exists merely for helping Bert> debugging.
I meant the primitive it invokes. Encapsulated magic is still magic.
So code would merely have to execute the equivalent of the primitives behind #instVarAt: and #instVarAt:put:, and no amount of wrapper class would help.
Bert> All you need to do to prevent the debugger from accessing instance Bert> variables is overwriting the methods the debugger invokes.
Ahh, but a determined outsider could still add methods to the class of the object on the fly, hand-compiling them if necessary.
Unless you're now voting for an immutable method dictionary. :)
Am 02.10.2008 um 11:25 schrieb Randal L. Schwartz:
"Bert" == Bert Freudenberg bert@freudenbergs.de writes:
Bert> There is no magic in #instVarAt:. It exists merely for helping Bert> debugging.
I meant the primitive it invokes. Encapsulated magic is still magic.
So code would merely have to execute the equivalent of the primitives behind #instVarAt: and #instVarAt:put:, and no amount of wrapper class would help.
Bert> All you need to do to prevent the debugger from accessing instance Bert> variables is overwriting the methods the debugger invokes.
Ahh, but a determined outsider could still add methods to the class of the object on the fly, hand-compiling them if necessary.
How would that outsider get at the class of the object?
Unless you're now voting for an immutable method dictionary. :)
-- Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095 merlyn@stonehenge.com URL:http://www.stonehenge.com/merlyn/ Smalltalk/Perl/Unix consulting, Technical writing, Comedy, etc. etc. See http://methodsandmessages.vox.com/ for Smalltalk and Seaside discussion
- Bert -
"Bert" == Bert Freudenberg bert@freudenbergs.de writes:
Bert> How would that outsider get at the class of the object?
I believe #class is "NoLookup", meaning that I can't define a method of my own to do something weird with that.
"Randal" == Randal L Schwartz merlyn@stonehenge.com writes:
Randal> I believe #class is "NoLookup", meaning that I can't define a method Randal> of my own to do something weird with that.
Feh. Ignore me. I have no idea what I'm talking about. :)
beginners@lists.squeakfoundation.org