Search Top Index
HELP METAFLAVOURS Mark Rubinstein April 1986 Updated A.Schoter June 1991 Metaflavours are part of the flavours package. For details of the package see TEACH * FLAVOURS. For details of the messages that metaflavours respond to see REF * METAFLAVOUR_FLAVOUR Metaflavours are instances that represent flavours. When you first define a new flavour an instance of the appropriate metaflavour (usually flavour) is created to hold the description of the flavour environment. Whenever a new flavour is defined the message "initialise" is sent to the instance with an empty list as argument. Whenever a flavour is changed the message "flavour_changed" is sent (with no argument). The default method for "flavour_changed" is to do nothing. The system provides three different metaflavours: metaflavour, mixin and flavour. For details on how to define new metaflavours see TEACH * FLAVOURS /Metaflavours. See HELP * FLAVOUR_LIBRARY for details of how flavour protocols are documented. The diagram shows 3 kinds of metaflavour that are provided in the system - these are metaflavour, used as the metaflavour of metaflavours (it is its own metaflavour), flavour which is what is created by default, and mixin which is the class of flavours which encapsulate a useful feature but which are not of themselves sensible to instantiate. The diagram also shows too examples of flavours (person_flavour) and (professor_flavour). This is NOT a diagram of the inheritance network. +-+ V | +-----+-----+ |metaflavour| +-----------+ ^ ^ | | +-----+ +----+ +---+---+ +--+--+ |flavour| |mixin| +-------+ +-----+ ^ ^ ^ | | | +-----+ +--+ | +--+---+ +----+----+ +---+---+ |person| |professor| |vanilla| +------+ +---------+ +-------+ So both person_flavour and professor_flavour are instances of flavour_flavour which is an instance of metaflavour_flavour, while vanilla_flavour is an instance of mixin_flavour which is an instance of metaflavour_flavour. Metaflavour_flavour is an instance of itself. (For interest, mixin and flavour inherit from metaflavour and metaflavour inherits from vanilla.) One of the methods that is only defined in flavour (but not in metaflavour) is "new" which will return an instance of the flavour. This is what -make_instance- uses before it sends the message initialise to the object. For example: vars judith; person_flavour<-new -> judith; judith <- initialise([name judith age 21 sex female]); ** [new person called judith is born] When you define a new flavour you can specify that its metaflavour should be something other than flavour by using the keyword "a" after the name of the flavour. (This should come before any "isa" inheritance statement or the keyword "novanilla".) For example suppose you want to define a mixin that provides a dated feature. This could be mixed with other flavours but you could not create an instance of it. flavour dated_object a mixin; ;;; inherit only from vanilla. ivars creation_date; defmethod after initialise; sysdaytime() -> creation_date; enddefmethod; endflavour; flavour person isa dated_object; ;;; mix dated_object with person endflavour; vars tom = make_instance([person name tom age 25 sex male]); ** [initlist is [name tom age 25 sex male]] ** [new person called tom is born] tom <- creation_date => ** Wed Apr 16 16:59:51 GMT 1986 You may wish to skip over the next bit to the SELF and MYFLAVOUR section. -- Defining a Metaflavour ---------------------------------------------- You can define you own metaflavours too. It is wise for metaflavours to inherit from the flavour metaflavour, since it provides many methods that are useful for manipulating flavours. For details of the methods that metaflavour provides see REF * METAFLAVOUR_FLAVOUR. One of the methods that you can provide in a metaflavour is "precedence_list". If you define such a method then it will be used for creating the precedence list of its instances. For example suppose you wanted to create a funny kind of flavour where the most general method is used instead of the most specific you could do something like this (note that for simplicities sake we are only dealing with single inheritance here). ;;; flavour inherits from metaflavour so no need to specify it. flavour sillyflavour a metaflavour isa flavour; defmethod precedence_list; lvars complist superf; ;;; construct a single inheritance precedence list and then ;;; reverse it to give most general first. ;;; get my components (the method components is provided ;;; by metaflavour self<-components -> complist; [% self; ;;; precedence lists include the flavour until null(complist) do hd(complist) -> superf; superf; superf<-components -> complist; enduntil; %].rev; ;;; reverse the list enddefmethod; defmethod printself; printf('<sillyflavour %p>', [^name]); enddefmethod; endflavour; sillyflavour_flavour => ** <metaflavour sillyflavour> ;;; make a simple flavour flavour general; defmethod m; [m in general] => enddefmethod; defmethod before m; [before m in general] => enddefmethod; defmethod after m; [after m in general] => enddefmethod; endflavour; ;;; make a silly flavour; flavour specific a sillyflavour isa general; defmethod m; [m in specific] => enddefmethod; defmethod before m; [before m in specific] => enddefmethod; defmethod after m; [after m in specific] => enddefmethod; endflavour; specific_flavour => ** <sillyflavour specific> vars i = make_instance([specific]); i <- m; ** [before m in general] ;;; reverse order from normal ** [before m in specific] ** [m in general] ** [after m in specific] ** [after m in general] NOTE: currently it is not possible to change the precedence list of metaflavours themselves (i.e. defining a precedence_list method in metaflavour will have no affect). -- Communicating with a Metaflavour ------------------------------------ You can send messages to metaflavours in the same way as normal instances. For details of the messages that metaflavours will respond to and how they respond, see REF * METAFLAVOUR_FLAVOUR --- C.all/help/metaflavours ----<Copyright University of Sussex 1986. All rights reserved.>-------