Well, when you talk about "THE copying machinery" you have to be a bit more specific. There is no such thing as #deepCopy or #shallowCopy in the ANSI Smalltalk standard. Many Smalltalks have Object>>copy ^self shallowCopy postCopy and encourage you to override #postCopy. But nothing stops you doing MyClass methods for: 'copying' copy ^self deepcopy ^self postCopy ^self shallowCopy ^self You will note that in Pharo, AtomicCollection, Behavior, Boolean, Character, Float, SmallFloat64, Form, ColorForm, Morph, Paragraph, Point, SmallInteger, String, UndefinedObject, and perhaps others override #deepCopy. Also, Boolean, Character, Float, SmallFloat64, SmallInteger, Symbol, UndefinedObject, and perhaps others override #shallowCopy. So it *is* possible to have singletons in Smalltalk. Classes can be copied in Pharo because someone thought it would be a good idea. On to the next point. 'I have an object whose internal state is updated by incoming messages. I need to take immutable snapshots of that object's state at some points. And that I do by sending "deepCopy" and then "beRecursivelyReadOnlyObject".' You do not know which objects will be copied by #deepCopy and which won't, or if you do, you cannot be sure that that will not change in a future release, or indeed if you load a package. You do not know whether some of these objects will break if made read-only. #deepCopy is *serious* "Hic sunt dracones" territory. It's marked on the Hunt-Lenox Globe, just beside the Vesuvian introitus ad infernum. Seriously, the OOP way to do this is MyClass>>immutableSnapshot "Answer an immutable copy of myself." ... and then whatever it takes to make precisely that happen. On Fri, 1 Jan 2021 at 23:35, Konrad Hinsen <konrad.hinsen@fastmail.net> wrote:
"Richard O'Keefe" <raoknz@gmail.com> writes:
#deepCopy is one of those things that is best avoided, because it violates the key principle of OOP that an
In the abstract, I agree. In practice, I don't see what else I could do for my use case. I have an object whose internal state is updated by incoming messages. I need to take immutable snapshots of that object's state at some points. And that I do by sending "deepCopy" and then "beRecursivelyReadOnlyObject".
Benoit St-Jean via Pharo-users <pharo-users@lists.pharo.org> writes:
It never occurred to me that it would ever be the case! I've always thought classes were singleton and that SomeClass copy would always return the sole instance of that class!
Me too. But after taking a closer look at how copy and deepCopy work, it seems that maintaining singletons under copy operations is impossible. There is no way to tell the copying machinery to return the original object instead of making a new one. Unlike e.g. Python, where this is possible and even quite common.
Konrad.