pharo icon indicating copy to clipboard operation
pharo copied to clipboard

Be robust against unintentionally sending #initialize to a Trait

Open koendehondt opened this issue 6 months ago • 5 comments

Bug description

Object class>>#initialize is implemented as:

initialize 

	"This method is empty but this is on purpose. This is to protect subclasses that are wrongly calling super initialize or classes that are receiving initialize.
	
	If you remove this method, the method Behavior >> initialize will be executed and the class will be nuked because reinitialized."

That is a nice safety net for the reasons described in the method comment.

However, there is no safety net for initializing Traits by accident. If one would try initializing a Trait, e.g. MyTrait initialize, then ClassDescription>>#initialize does the initialization:

initialize

	super initialize.
	self resetProtocols

The super send triggers Behavior>>#initialize:

initialize
	"moved here from the class side's #new"
	super initialize.
	self basicSuperclass: Object.
	"no longer sending any messages, some of them crash the VM"
	self methodDict: self emptyMethodDictionary.
	self setFormat: Object format

This method clears the method dictionary. That is not desired. When making the mistake to initialize Traits as part of initializing all classes in a baseline for instance, it is very confusing that after loading the baseline, traits have no methods.

Suggested fix

It would be better to put a safety net in place for such mistakes, similar to Object class>>#initialize. A new method Trait>>#initialize could be the safety net:

initialize 
	"This method is empty but this is on purpose. This is to protect subclasses that are receiving initialize.
	
	If you remove this method, the method Behavior >> initialize will be executed and the trait will be nuked because reinitialized."

Another implementation could be to not be silent and signal an error.

Version information

  • Pharo 13

Additional context

cc @MarcusDenker This is the root cause of the problem I discussed and investigated with you during the Pharo Sprint of May 23, 2025.

If this bug report is considered to be valid, I am happy to create PR with the suggested fix.

koendehondt avatar Jun 02 '25 17:06 koendehondt

Tx good catch! I thought that we fixed the Object class >> initialize too. I remember working on it.

Ducasse avatar Jun 03 '25 07:06 Ducasse

Do not you think that the solution should be

Trait class>> initialize
...

Ducasse avatar Jun 03 '25 07:06 Ducasse

@Ducasse I made a stupid mistake. Of course the class method #initialize has to be implemented with an empty body:

Trait class >> #initialize
	"This method is empty but this is on purpose. This is to protect subclasses that are receiving initialize.
	
	If you remove this method, the method Behavior >> initialize will be executed and the trait will be nuked because reinitialized."

koendehondt avatar Jun 03 '25 19:06 koendehondt

Tx good catch! I thought that we fixed the Object class >> initialize too. I remember working on it.

You did. That is what I wrote at the top of the ticket 😀. Object class>>#initialize is empty.

koendehondt avatar Jun 03 '25 19:06 koendehondt

Nice, I will do PRs for both Pharo13 and Pharo14

MarcusDenker avatar Jun 04 '25 08:06 MarcusDenker

This has been fixed

jecisc avatar Jun 26 '25 11:06 jecisc

Thank you!

koendehondt avatar Jun 26 '25 12:06 koendehondt