Hello,
I was reading Kent Beck's "Guide to Better Smalltalk" recently and ran across an article on instance-specific behavior. It seemed like a lot of fun and something to oh and ah the java folks. Anyway, I typed the following in a workspace: | b md inst | b:=Behavior new. b instanceSpec: Object instanceSpec. b methodDictionary: MethodDictionary new. b superclass: Object. b basicCompile: 'dodo ^''la la'''. b inspect. Now, if I select and "Evaluate It". I get an inspector on my new Behavior object. There are no methods in his method dictionary at all! Is this right? Anyway, I replaced Behavior with ClassDescription and re-did it. This time, I get a message in my inspectors that #name is the subclasses responsibility. OK, So I implemented a TempClassDescription with #name implemented to return 'foo'. And re-ran with my TempClassDescription and I still get no methods in my method dictionary! Alright, I change TempClassDescription to Class and re-ran it. Still no methods, so I then used Metaclass and my methods appeared (even though they showed their class as nil) and creating a new instance worked and responded to: #dodo. But, this seems a little much since Metaclass should be a soleInstance. Anyway, how I should go about getting instance specific behavior in Dolphin. I also tried this in Squeak and got some interesting results as well. The code above is pretty much taken from Kent's article, but made simpler for my excursions...Anyway, I was just playing around with this stuff....=) Seemed cool to me.... Thanks, Blaine Buxton |
Blaine,
From a message posted to this group in January, see below. Please note that the #assumeInstanceBasedBehavior method has now been included in the Dolphin 5 base system as Object>>allowPerInstanceBehavior (so it won't need to be re-added). Best Regards, Andy Bower Dolphin Support http://www.object-arts.com --- Are you trying too hard? http://www.object-arts.com/Relax.htm --- ----- Folks, An interesting post came up in c.l.s recently with someone wanting to see if instance based behaviour could be added to objects in Smalltalk (and in this case Dolphin). Rather than cross post my reply (which might result in excess pollution) I've just decide to post my reply separately here. Some of you may find this amusing to play with. "Artur Biesiadowski" <[hidden email]> wrote in message news:[hidden email]... > >> Is there any smalltalk-like system which allows you to redefine > >> behaviour of single instance ? Instead of redefining method for class, > >> do it only for single instance and only then maybe propagate it to > >> entire system. > > > > You can do that in Smalltalk. Or Lisp. > > So I can get Dolphin Smalltalk for example, create collection of 20 > instance of my class, select one of them, do something (what method > should I call?) and normal method edition window will appear, but just > modifying code for this single instance ? And if I'll clear contents of > array, what will happen to code ? It will be deleted automagically or > orphaned ? In latter case, how can I access it later ? Yes, and this is how you do it. The following code is for Dolphin. Most Smalltalks will be able to do something similar but the implementation will typically be via private methods and so won't be consistent between dialects. If you haven't got a copy of Dolphin yet then try this with the 30 day Dolphin Professional trial version available at: http://www.object-arts.com/Trial Fire up the IDE and open a workspace. Copy the following into the workspace, select it, and then choose Workspace/File it in. +++ snip after this line +++ !Object methodsFor! assumeInstanceBasedBehavior "Private - Make the receiver a prototypical instance of it's own private class. From this point on the instance may have it's own behaviour modified or added to." | metaSuperclass newMetaclass newClass | "Create a private new metaclass" metaSuperclass := self class class. (newMetaclass := Metaclass new) methodDictionary: MethodDictionary new; instanceSpec: metaSuperclass instanceSpec; superclass: metaSuperclass. "Create a private instance of this metaclass as the new class" (newClass := newMetaclass new) methodDictionary: MethodDictionary new; instanceSpec: self class instanceSpec; setName: ('_', self class name) asSymbol; superclass: self class. self becomeA: newClass.! ! !Object categoriesFor: #assumeInstanceBasedBehavior!private! ! +++ snip before this line +++ I'm not sure the formatting will make it through NNTP but it should work anyway. This is a new method added to Object (and in this case I think it *is* appropriate to extend Object - just harking back to another thread). The method creates a new private (hidden) class and metaclass pair for any object that has #assumeInstanceBasedBehavior called on it. This pair hold their own private method dictionaries so prototypical methods can be added. Note you can add both instance and class based prototypical methods. The new classes will not be visible in the standard browsers but could be made so if necessary. They will also disappear and be garbage collected when the prototypical object has no remaining references. Let' test this out. Copy the following into a Dolphin workspace and execute each line individually (place the cursor on the line and press Ctrl+E). Stuff in "" is comment. When you see a line with "Ctrl+D" then press this and it will evaluate the line and display a result. We'll work on Dates for a simple but rather boring demo. a := Date today. "Ctrl+D" b := Date today. c := Date today. Three dates. Add them to an array (your suggestion) array := Array with: a with: b with: c. "Ctrl+D" Let's make the first two have prototypical behaviour. a assumeInstanceBasedBehavior. b assumeInstanceBasedBehavior. Ask for the weekdays of the days in the array. array collect: [:each | each weekday ]. "Ctrl+D" No surprise there. Even thought the first two have the capability of prototypical behaviour they are inheriting from their original class (Date). Now let's add that "Friday feeling" to the first date only. We'll change the behaviour of the #weekdayIndex method to always answer 5. Then see what happens when we ask for the #weekday again (which makes use of #weekdayIndex). Note we use the standard compiler to compile in the new method into a's class. a compile: 'weekdayIndex ^5'. Now ask for the days again: array collect: [:each | each weekday ]. "Ctrl+D" Assuming that it's not actually Friday when you try this you should see a difference. Notice that only the first date has got the new behaviour. The second prototypical date is still inheriting directly from Date. Try modifying it's code for a Saturday. a compile: 'weekdayIndex ^6'. array collect: [:each | each weekday ]. "Ctrl+D" Now lets see how we can tell these are different from normal Dates array collect: [:each | each class ]. "Ctrl+D" Try looking for _Date in the Class Hierarchy Browser; it should be nowhere to be found. You can find the hidden classes by a roundabout route: (Metaclass allInstances collect: [:each | each instanceClass]) select: [:each | each superclass == Date] "Ctrl+D" Now free up our variables and look again: a := b := c := array := nil. (Metaclass allInstances collect: [:each | each instanceClass]) select: [:each | each superclass == Date] "Ctrl+D" You should find that the _Date classes have disappeared automagically. I notice from your original post that you wanted to be able to view the instance based methods in a browser. This would be fairly easy to arrange but is beyond the scope of this excercise. Still, I hope you've found the above to be amusing and food for thought. Best Regards, Andy Bower Object Arts Ltd. http://www.object-arts.com --- Are you trying too hard? http://www.object-arts.com/Relax.htm --- |
In reply to this post by Blaine Buxton
> "Blaine Buxton" <[hidden email]> schrieb im Newsbeitrag
news:[hidden email]... > Hello, > I was reading Kent Beck's "Guide to Better Smalltalk" recently and ran > across an article on instance-specific behavior. It seemed like a lot of > fun and something to oh and ah the java folks. Anyway, I typed the > following in a workspace: Andy posted an example for instance specific behaviour here some time ago. I built a package with Andys Code but with an interface similar to the one mentioned in Kent Beck's Book. If your news server strips binary attachments you can download it at http://www.homeaddress.de/US_Specialized_Instances.zip Udo begin 666 US Specialized Instances.pac M?"!P86-K86=E('P-"G!A8VMA9V4@.CT@4&%C:V%G92!N86UE.B G55,@4W!E M8VEA;&EZ960@26YS=&%N8V5S)RX-"G!A8VMA9V4@<&%X5F5R<VEO;CH@,#L- M"@EB87-I8T-O;6UE;G0Z("<G+@T*#0IP86-K86=E(&)A<VEC4&%C:V%G959E M<G-I;VXZ("<P+C P-"<N#0H-"B)!9&0@=&AE('!A8VMA9V4@<V-R:7!T<R(- M"@T*(D%D9"!T:&4@8VQA<W,@;F%M97,L(&QO;W-E(&UE=&AO9"!N86UE<RP@ M9VQO8F%L(&YA;65S+"!R97-O=7)C92!N86UE<R(-"G!A8VMA9V4@8VQA<W-. M86UE<PT*"7EO=7)S96QF+@T*#0IP86-K86=E(&UE=&AO9$YA;65S#0H)861D M.B C3V)J96-T("T^("-I<U-P96-I86QI>F5D.PT*"6%D9#H@(T]B:F5C=" M M/B C<W!E8VEA;&EZ93L-"@EA9&0Z("-/8FIE8W0@+3X@(W-P96-I86QI>F4Z M.PT*"7EO=7)S96QF+@T*#0IP86-K86=E(&=L;V)A;$YA;65S#0H)>6]U<G-E M;&8N#0H-"G!A8VMA9V4@<F5S;W5R8V5.86UE<PT*"7EO=7)S96QF+@T*#0HB M0FEN87)Y($=L;V)A;"!.86UE<R(-"G!A8VMA9V4@8FEN87)Y1VQO8F%L3F%M M97,Z("A3970@;F5W#0H)>6]U<G-E;&8I+@T*(E)E<V]U<F-E($YA;65S(@T* M<&%C:V%G92!A;&Q297-O=7)C94YA;65S.B H4V5T(&YE=PT*"7EO=7)S96QF M*2X-"@T*(D%D9"!T:&4@<')E<F5Q=6ES:71E(&YA;65S(@T*<&%C:V%G92!S M9710<F5R97%U:7-I=&5S.B H261E;G1I='E3970@;F5W#0H)861D.B G1&]L M<&AI;B<[#0H)>6]U<G-E;&8I+@T*#0IP86-K86=E(0T*#0HB0VQA<W,@1&5F M:6YI=&EO;G,B(0T*#0HB3&]O<V4@365T:&]D<R(A#0H-"B%/8FIE8W0@;65T M:&]D<T9O<B$-"@T*:7-3<&5C:6%L:7IE9 T*"5YS96QF(&-L87-S(&YA;64@ M8F5G:6YS5VET:#H@)U\G(0T*#0IS<&5C:6%L:7IE#0H)(E!R:79A=&4@+2!- M86ME('1H92!R96-E:79E<B!A('!R;W1O='EP:6-A;"!I;G-T86YC92!O9B!I M="=S(&]W;B!P<FEV871E#0H)8VQA<W,N($9R;VT@=&AI<R!P;VEN="!O;B!T M:&4@:6YS=&%N8V4@;6%Y(&AA=F4@:70G<R!O=VX@8F5H879I;W5R(&UO9&EF M:65D(&]R(&%D9&5D('1O+B(-"@T*"7P@;65T85-U<&5R8VQA<W,@;F5W365T M86-L87-S(&YE=T-L87-S('P-"@T*"2)#<F5A=&4@82!P<FEV871E(&YE=R!M M971A8VQA<W,B#0H);65T85-U<&5R8VQA<W,@.CT@<V5L9B!C;&%S<R!C;&%S M<RX-"@DH;F5W365T86-L87-S(#H]($UE=&%C;&%S<R!N97<I#0H)"6UE=&AO M9$1I8W1I;VYA<GDZ($UE=&AO9$1I8W1I;VYA<GD@;F5W.PT*"0EI;G-T86YC M95-P96,Z(&UE=&%3=7!E<F-L87-S(&EN<W1A;F-E4W!E8SL-"@D)<W5P97)C M;&%S<SH@;65T85-U<&5R8VQA<W,N#0H-"@DB0W)E871E(&$@<')I=F%T92!I M;G-T86YC92!O9B!T:&ES(&UE=&%C;&%S<R!A<R!T:&4@;F5W(&-L87-S(@T* M"2AN97=#;&%S<R Z/2!N97=-971A8VQA<W,@;F5W*0T*"0EM971H;V1$:6-T M:6]N87)Y.B!-971H;V1$:6-T:6]N87)Y(&YE=SL-"@D):6YS=&%N8V53<&5C M.B!S96QF(&-L87-S(&EN<W1A;F-E4W!E8SL-"@D)<V5T3F%M93H@*"=?)RP@ M<V5L9B!C;&%S<R!N86UE*2!A<U-Y;6)O;#L-"@D)<W5P97)C;&%S<SH@<V5L M9B!C;&%S<RX-"@T*"7-E;&8@8F5C;VUE03H@;F5W0VQA<W,N(0T*#0IS<&5C M:6%L:7IE.B!A4W1R:6YG#0H)<V5L9B!S<&5C:6%L:7IE+@T*"7-E;&8@8VQA M<W,@8V]M<&EL93H@85-T<FEN9PT*(2 A#0HA3V)J96-T(&-A=&5G;W)I97-& M;W(Z("-I<U-P96-I86QI>F5D(7!R:79A=&4A<W!E8VEA;&EZ:6YG(2 A#0HA M3V)J96-T(&-A=&5G;W)I97-&;W(Z("-S<&5C:6%L:7IE(7!R:79A=&4A<W!E M8VEA;&EZ:6YG(2 A#0HA3V)J96-T(&-A=&5G;W)I97-&;W(Z("-S<&5C:6%L M:7IE.B%P<FEV871E(7-P96-I86QI>FEN9R$@(0T*#0HB16YD(&]F('!A8VMA M9V4@9&5F:6YI=&EO;B(A#0H-"B -"B)":6YA<GD@1VQO8F%L<R(A#0H-"B)2 .97-O=7)C97,B(0T*#0H` ` end |
In reply to this post by Andy Bower
Blaine,
Sorry, I just realized (thanks to your e-mail) that the Object>>allowPerInstanceBehavior method is not shipped in the standard D5 product. I've uploaded the package to our website: http://www.object-arts.com/Lib/Downloads/5.0/Per%20Instance%20Behavior.zip Stick this in % Best Regards, Andy Bower Dolphin Support http://www.object-arts.com --- Are you trying too hard? http://www.object-arts.com/Relax.htm --- |
Free forum by Nabble | Edit this page |