[Pharo-dev] Re: A little post Why class number is an idiotic quality metric?

2024-02-10 Thread James Foster via Pharo-dev
For those that didn't write the post, here is a link…

https://pharoweekly.wordpress.com/2024/02/10/why-class-number-is-an-idiotic-quality-metric/

James

> On Feb 10, 2024, at 1:13 AM, stephane ducasse  
> wrote:
> 
> 
> https://wordpress.com/post/pharoweekly.wordpress.com/4226
> 
> 
> Stéphane Ducasse
> http://stephane.ducasse.free.fr
> 06 30 93 66 73
> 
> "If you knew today was your last day on earth, what would you do differently? 
> ESPECIALLY if, by doing something different, today might not be your last 
> day on earth.” Calvin & Hobbes
> 
> 
> 
> 
> 



[Pharo-dev] Re: About removing class side initialization

2024-01-17 Thread James Foster via Pharo-dev
Stef,

Your comments brought to mind a few thoughts.

First, initialize methods should, in general, be idempotent; that is, running 
them repeatedly should not make further changes after the first run (along the 
lines of your mention of lazy initialization). For example, if a variable is 
nil then it should be set to an empty set; if it is already a set, don’t 
replace it.

Second, many packaging systems have scripts for pre-load, post-load, 
pre-remove, and post-remove. Instead of having initialize methods on a class, 
we could have scripts associated with a package. (Presumably a package will be 
a first-class object and have methods to handle these action.)

Third, following a model from upgrading databases, one would have a “version 
number” stored somewhere (perhaps a class variable) and scripts that upgrade 
and downgrade the version. Rerunning the “upgrade” would be idempotent since we 
would already be on the latest version.

As to the specific situation, yes, there is a problem with 
Behavior>>#initialize that arises from Behavior’s unique position where 
instances are classes and we have an unfortunate gratuitous polymorphism 
between instance initialization in which we are creating a new instance of 
Behavior (and giving it an empty method dictionary) and class initialization 
which is typically associated with _loading_ or _installing_ a class. Perhaps 
with a time machine the right solution would be separate names for these 
concepts (#initialize for instances, and #postLoad for classes). But really, 
the only place this is confusing is with Behavior, so maybe we should treat it 
as a special case rather than reaching for a general solution.

I think that rather than trying to prevent calling super initialize on classes 
(when failing to call super initialize on instances is a common bug) or trying 
to prevent an initialize from reaching Behavior>>initialize (by blocking it on 
the class side of Object), we should simply have Behavior>>initialize recognize 
its special position (and unique risk for confusion) by being idempotent. That 
is, if we already have a method dictionary, then there is no reason to do any 
further initialization; just protect the existing code with a check of “are we 
already initialized?” (Do the simplest thing that could possible work!)

So, while we could look at bigger solutions like package managers or image 
versions, we should just start by making Behavior>>#initialize smart enough to 
recognize its unique danger and handle the problem there. I don’t like the 
situation in which some initialize methods _must_ call super and some 
initialize methods _must not_ call super. 

In fact, I could imagine that there are some times when class initialization 
_should_ call super. Perhaps I have an abstract superclass that builds and 
caches a list of its subclasses (in GemStone this would be non-trivial). When a 
new subclass is added and the subclass is initialized, I want the super 
initialize method to be called so the superclass can reinitialize its cache. 
Perhaps this is a contrived case, but the point is that it isn’t really 
appropriate to put in a rule that you should not send super initialize.

Just some ideas and thoughts to let you know I’m reading your posts…

James Foster


> On Jan 17, 2024, at 12:37 PM, stephane ducasse  
> wrote:
> 
> Hi community
> 
> I would like to get use your ideas. 
> 
> Here is the case
> 
> Context: Class side initialize are not good.
>   We fixed a bug with guille today (should do a PR) this bug was breaking 
> some projects by changing the superclass of classes to Object. Radical!
> 
>   It was produced by the removal of DependentFields in Object and the 
> removal of the class side Object initialize method
>   Needed to initialize DependentFields (RIP).
> 
>   Doing so when a class was doing a super initialize it executes the 
> Behavior>>#initialize  (which reinitialize the class and its superclass) and 
> was not reachable before because blocked by Object class>>#initialize.
> 
> Two Situations. 
> 
>   When we do a class super initialize there are two cases
> 
>   Case 1. the super reaches Behavior>>#initialize and your class gets 
> killed.
>   Solution 1. Easy we will define a class side initialize method to 
> protect the execution of Behavior>>#initialize.
>   Ideally raising a warning so that people can find their problems.
> 
>   Case 2. 
>   You have a little hierarchy Root and Subclass1 Subclass2 classes
>   Root class defines an initialize method. 
>   
>   You should not redefine initialize in Subclass1 and do a super 
> initialize
>   else we get a double initialize. Not easy to grasp so I guess 
> that many people are making this mistake. 
> 
>   Solution 2. 
>   Cyril added a rule in a ReleaseTest (yes this is cool and we 
> should use more rules and not code by hand in the releaseTest)
>