Squeak
  links to this page:    
View this PageEdit this Page (locked)Uploads to this PageHistory of this PageTop of the SwikiRecent ChangesSearch the SwikiHelp Guide
Menus perform:orSendTo:
Last updated at 4:33 pm UTC on 14 January 2006
Samuel Tardieu September 20, 2004 4 I wonder why the implementation of Object>>#perform:#orSendTo: looks counterintuitive to me:
perform: selector orSendTo: otherTarget
	"If I wish to intercept and handle selector myself, do it;
         else send it to otherTarget"
	^ otherTarget perform: selector
I would have naively thought that a correct implementation was:
  (self respondsTo: selector) ifTrue: [ ^self perform: selector ]
                              ifFalse: [ ^otherTarget perform: selector ]
Can I find somewhere an explanation of how this selector is supposed to be used?

Stephan Rudlof If there is an implementation of selector, it resides in a sub-class of Object and will be performed automatically, since the corresponding message will be send to the subclass corresponding to the receiver object first. On the other hand, if there is no sub-class of Object implementing selector, the method in Object comes into play (method lookup goes from the subclass corresponding to the receiver up to Object).

Boris Gaertner Its main purpose is support for menues. The MouseMenuController gives the model a chance to perform a selected activity, but it will perform a default activity when the model refuses to do something. This is in MouseMenuController>>pluggableYellowButtonActivity. Here, the menu is sent the message invokeOn: model orSendTo: self.
#invokeOn:orSendTo: has only two implementors, the Menus perform:orSendTo: and the SelectionMenu. The CustomMenu uses
  recipient perform: aSelector orSendTo: alternateServiceProvider
and the SelectionMenu implements delegation to the most suitable service provider with this statement:
  (targetObject respondsTo: aSelector)
     ifTrue:
       [targetObject perform: aSelector]
     ifFalse:
       [anObject perform: aSelector]
This is your proposal again.

Most implementors of #perform:orSendTo: are in fact models that provide support for some (or all) of their menue options. Note that Model, the superclass of most application models, has this definition:
  perform: selector orSendTo: otherTarget
   "Selector was just chosen from a menu by a user.
     If can respond, then perform it on myself.
     If not, send it to otherTarget, presumably the
     editPane from which the menu was invoked." 

  "default is that the editor does all"
  ^ otherTarget perform: selector.
That is, the default behaviour of a model is to refuse responsibility for the menu items! I am not aware of uses of #perform:orSendTo: that are not related to menues.
Lex Spoon So, why build menus whose menu items do not know who to target? Instead of having one target for the whole menu, why not specify a target for each item, and set the target correctly?
Boris Gaertner Well, CustomMenus have their targets (one for every menu item if a common target is not a suitable choice), but the simpler SelectionMenus do not have a target at all. Classes PopUpMenu and SelectionMenu are remnants from MVC, but they have their advantages: Just because they do not have targets, they can be used on a "build once, use forever" policy. That policy is further supported by the convention that a controller should provide a default implementation, but the model should be given a chance to do something different.

A "build once - use forever" menu can live in the image for years. Some prominent examples are:
StandardSystemController >>ScheduledBlueButtonMenu
ParagraphEditor>> TextEditorYellowbuttonMenu

A CustomMenu can be created for quite short-living targets, e.g. for a morph, a view or the like. It is obvious that such menues should not be stored for repeated use. CustomMenues are very convenient,but they are used under a "use once and throw away" policy.