MessageSend.st
author Claus Gittinger <cg@exept.de>
Sat, 11 Nov 1995 16:28:41 +0100
changeset 530 07d0bce293c9
parent 383 8e3ec8164440
child 1183 e3d58d115e53
permissions -rw-r--r--
uff - version methods changed to return stings

"
 COPYRIGHT (c) 1994 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"

Message subclass:#MessageSend
	 instanceVariableNames:'receiver'
	 classVariableNames:''
	 poolDictionaries:''
	 category:'Kernel-Methods'
!

!MessageSend class methodsFor:'documentation'!

copyright
"
 COPYRIGHT (c) 1994 by Claus Gittinger
	      All Rights Reserved

 This software is furnished under a license and may be used
 only in accordance with the terms of that license and with the
 inclusion of the above copyright notice.   This software may not
 be provided or otherwise made available to, or used by, any
 other person.  No title to or ownership of the software is
 hereby transferred.
"
!

version
    ^ '$Header: /cvs/stx/stx/libbasic/MessageSend.st,v 1.7 1995-11-11 15:21:25 cg Exp $'
!

documentation
"
    Instances of MessageSend can be used for simulation programs.
    They keep some receiver, selector and arguments and can be evaluated
    at any time later.
    They can also be used as replacement for simple [self foo]-blocks.
    Of course, they could also be replaced by blocks such as
    '[receiver perform:selector withArguments:arguments]', 
    but blocks are somewhat more expensive in their creation and require
    more storage.

    However, the send-operation itself is faster in a block, since it
    will use a better caching scheme (inline-cache) for its send, while
    sending here is done with a #perform:, which is not inline-cached. 
    Thus it is not sure, which one is actually better to use ...

    You can either store arguments in the messageSend object, or
    leave them undefined until the send is actually performed, and
    pass any arguments with the value:-messages.

    If you plan to write a simulator and want to queue cillions of blocks,
    try to use MessageSends instead of blocks
    (or even: message, if the receiver is constant);
    this will save you a lot of memory.

    Example:

       |m|

       m := MessageSend receiver:1 selector:#+ arguments:#(2).
       m value. 

       is almost the same as:

       |m|

       m := [1+2].
       m value. 


    Example2 (a simulation)
	|q|

	q := Queue new.
	...
	'put some action into the queue'
	q nextPut:(MessageSend receiver:someone selector:#foo arguments:#().
	...
	'evaluate next action from the queue'
	q next value
	...

    if all sends are going to the same receiver, use:
	|q|

	q := Queue new.
	...
	'put some action into the queue'
	q nextPut:(Message selector:#foo arguments:#().
	...
	'evaluate next action from the queue'
	q next sendTo:someone
	...
"
! !

!MessageSend class methodsFor:'instance creation'!

receiver:r selector:sel arguments:argArray
    |newMessage|

    newMessage := super new setSelector:sel arguments:argArray.
    newMessage receiver:r.
    ^ newMessage
! !

!MessageSend methodsFor:'evaluation'!

value
    "evaluate the messagesend with the original arguments"

    ^ receiver perform:selector withArguments:args
!

value:someArgument
    "evaluate the messagesend, with someArgument instead of the original"
 
    ^ receiver perform:selector with:someArgument
!

value:arg1 value:arg2
    "evaluate the messagesend, with arg1 and arg2 instead of the original
     arguments"

    ^  receiver perform:selector with:arg1 with:arg2
!

value:arg1 value:arg2 value:arg3
    "evaluate the messagesend, with arg1, arg2 and arg3 instead of the original
     arguments"

    ^  receiver perform:selector with:arg1 with:arg2 with:arg3
!

valueWithArguments:argArray
    "evaluate the messagesend, with arguments taken from argArray,
     instead of the original arguments"

    ^  receiver perform:selector withArguments:argArray
! !

!MessageSend methodsFor:'accessing'!

receiver:r
    "set the receiver"

    receiver := r
!

receiver
    "return the receiver"

    ^ receiver
!

numArgs
    ^ selector numArgs
! !

!MessageSend methodsFor:'printing & storing'!

displayString
    "return a string for display in inspectors etc."

    ^ 'MessageSend(' , receiver displayString , '>>' , selector , ')'
!

printOn:aStream
    "return a string for printing the receiver"

    receiver printOn:aStream.
    aStream nextPutAll:'>>'.
    selector printOn:aStream
! !