Is it possible to extend an individual object in Smalltalk

半城伤御伤魂 提交于 2019-11-29 01:56:36

In Smalltalk there is no built in way of doing instance-specific behavior in that way. Smalltalk adheres to the principle that each object belongs to a class and its behavior and state shape depends on the class. That is why you can easily change the class (add inst vars, compile new methods, etc), but that means changing the behavior to all of its instances. There are, however, different approaches (according to the Smalltalk flavor) for achieving instance-specific behavior, such as Lightweight Classes, where the idea is to create a special (lightweight) class for a particular instance and replace the original class with the custom one. As a result you have a special class for each "special" instance. AFAIK in Digitalk St the dispatching mechanism is a bit more flexible and allows to easily implement instance-based behavior (see 4th link). I'll leave here some links that you may find useful:

HTH

Edit: the link posted by Hernan ("Debugging Objects" by Hinkle, Jones & Johnson) is the one to which I was referring and that couldn't find.

Having instance specific behavior in Smalltalk basically involves changing a pointer class and a primitive call. The "Debugging Objects" article by Bob Hinkle, Vicki Jones, and Ralph E. Johnson, published in The Smalltalk Report, Volume 2#9, July-August 1993, contains all the explanations.

I have ported the original Lightweight classes code from the version released in 1995 by Bob Hinkle for VisualWorks 2.0. The VisualWorks source includes code divided in three packages named "ParameterizedCompiler", "Breakpoint" and "Lightweight". The reason of this division was generated by the desire of having separate and re-usable functionality. All of them have separate articles in OOP journals.

My Squeak/Pharo port contains an "Instances Browser", based on the OmniBrowser (and more documentation here) framework, which lets you browse and modify the instances adding the Lightweight behavior through the classic Smalltalk Browser UI. It would work in latest Squeak 4.x versions with little or no effort. Unfortunately the infrastructure of Pharo changed substantially from versions <= 1.2, therefore it may need some work to work it latest versions.

In VisualWorks, due to the deep changes in the VisualWorks GUI from 2.0 to 7.3, most of the tools to manage the lightweight classes were not included. If someone is interested, I can upload the parcel for VW 7.3

A basic script to test the lightweight classes features is:

| aDate |
aDate := Date today.
aDate becomeLightweight.
aDate dispatchingClass 
        compile: 'day ^42' 
      notifying: nil 
         ifFail: [self error].
aDate day inspect

Squeak Etoys heavily makes use of object-specific behavior and state. This is implemented as "uniclasses". When you create a script for an Etoys object (instance of Player class), then the object's class will be changed to a "uniclass", that is, a unique subclass of Player, which can have its own methods (corresponding to Etoys scripts) and instance variables (corresponding to Etoys user variables).

Other Squeak-based projects use "anonymous" uniclasses, which are not listed as subclass in its superclass. That means they are pretty much invisible as they do not show up in a System Browser, for example (whereas Etoys-style uniclasses do show up in the browser).

ewernli

A colleage has been working a new reflective API for Pharo Smalltalk that is called Bifrost. you can check the page of the Bifrost project.

His approach pushes instance-specific adapations at its core. Everything happens by binding metaobjects to regular objects in order to adapt them. Lower-level metaobjects can be composed into higher-level, coarse-grained, metaobject that define sensible adaptations, e.g. a profiling metaobject that will measure the time each invocation on the target object takes.

As @ewernli points out Bifrost basically makes Smalltalk an object-centric reflection system. All reflective changes are targeted first at objects instead of having an hybrid mechanism with classes. You can still do all the traditional class reflection but on top of object-centric reflection. What I think that is relevant of this new approach is a number of applications that we found that improves how we developed and perceived a live system:

Object-centric debugging completely changes the way we debug by concentrating on objects and allowing the developer to remain interacting with live objects rather than having to insert conditional breakpoints at source code level.

Talents are composable dynamic units of reuse, like traits but for objects. There are many more applications.

Frank Shearar

In Ruby, as far as I know, a method dictionary attaches to an object.

In Smalltalk, the method dictionary is bound to a Class object so, in a vanilla Smalltalk image, you can't write eigenclass-like things.

Having said that, there are a few prototype libraries: this question's answers mention quite a few.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!