[squeak-dev] The Trunk: Kernel-eem.1426.mcz

commits at source.squeak.org commits at source.squeak.org
Sat Nov 27 21:02:18 UTC 2021


Eliot Miranda uploaded a new version of Kernel to project The Trunk:
http://source.squeak.org/trunk/Kernel-eem.1426.mcz

==================== Summary ====================

Name: Kernel-eem.1426
Author: eem
Time: 27 November 2021, 1:02:15.155642 pm
UUID: 9ca49d5c-f988-4848-a26b-53b1f79d64a2
Ancestors: Kernel-ct.1425

Implement protection against infinite recursion of doesNotUnderstand: within Object>>doesNotUnderstand:.

Note: this implementation puts the additional error handler within Object>>doesNotUnderstand: and sends error: to the receiver on detecting recursion.  An alternative might be to introduce a protected form of sentTo:, which would more naturally send error to the message.  e.g. either of

Message methods for sending
sentWithProtectionAgainstRecursiveDoesNotUnderstandTo: receiver
	"Answer the result of sending this message to receiver, within a guard to
	 protect against infinite recursion."

	^[self sentTo: receiver]
		on: MessageNotUnderstood
		do: [:ex|
			(receiver == ex receiver
			and: [self hasIdenticalContentsAs: ex message]) ifTrue:
				[receiver error: 'infinite recursion in doesNotUnderstand:'].
			ex pass]

or

sentWithProtectionAgainstRecursiveDoesNotUnderstandTo: receiver
	"Answer the result of sending this message to receiver, within a guard to
	 protect against infinite recursion."

	^[self sentTo: receiver]
		on: MessageNotUnderstood
		do: [:ex|
			(receiver == ex receiver
			and: [self hasIdenticalContentsAs: ex message]) ifTrue:
				[self error: 'infinite recursion in doesNotUnderstand:'].
			ex pass]

I think this is too elaborate. Adding Message>>hasIdenticalContentsAs: is the key to making all variants concise enough.

=============== Diff against Kernel-ct.1425 ===============

Item was added:
+ ----- Method: Message>>hasIdenticalContentsAs: (in category 'comparing') -----
+ hasIdenticalContentsAs: aMessage
+ 	"Answer if the argument's selector and arguments are identically equal to those of the receiver.
+ 	 It is assumed that the argument aMessage is, in fact, a message."
+        selector ~~ aMessage selector ifTrue:
+ 		[^false].
+ 	1 to: args size do:
+ 		[:i| (args at: i) ~~ (aMessage arguments at: i) ifTrue: [^false]].
+ 	^true!

Item was changed:
  ----- Method: Object>>doesNotUnderstand: (in category 'error handling') -----
  doesNotUnderstand: aMessage 
  	 "Handle the fact that there was an attempt to send the given
  	  message to the receiver but the receiver does not understand
  	  this message (typically sent from the machine when a message
+ 	  is sent to the receiver and no method is defined for that selector).
- 	 is sent to the receiver and no method is defined for that selector)."
  
+ 	 Raise the MessageNotUnderstood signal.  If it is caught, answer
+ 	 the result supplied by the exception handler.  If it is not caught,
+ 	 answer the result of resending the message within a guard for
+ 	 infinite recursion. This allows, for example, the programmer to
+ 	 implement the method and continue."
+ 
  	"Testing: (3 activeProcess)"
  
  	| exception resumeValue |
  	(exception := MessageNotUnderstood new)
  		message: aMessage;
  		receiver: self.
  	resumeValue := exception signal.
+ 	^exception reachedDefaultHandler "i.e. exception was not caught..."
+ 		ifTrue:
+ 			[[aMessage sentTo: self]
+ 				on: MessageNotUnderstood
+ 				do: [:ex|
+ 					(self == ex receiver
+ 					and: [aMessage hasIdenticalContentsAs: ex message]) ifFalse:
+ 						[ex pass].
+ 					self error: 'infinite recursion in doesNotUnderstand:']]
- 	^exception reachedDefaultHandler
- 		ifTrue: [aMessage sentTo: self]
  		ifFalse: [resumeValue]!



More information about the Squeak-dev mailing list