with-stream-class

Macro

Package: excl

Arguments: (class-name &optional stream) &body body

Returns the resulting values of the body forms. Within the body, all sm, funcall-stm-handler, and funcall-stm-handler-2 forms are expanded in such a way that the access into the stream requires only one or two memory-reference instructions, as indicated next.

The decision as to whether to use the optional stream argument or not depends on whether there are more than one accesses anticipated. If two or more accesses are done within the body form, then the stream argument should be specified. If only one access is done, it is not necessary to specify the stream argument. However, if two with-stream-class forms are nested and the outer form specifies a stream argument, then the inner form must also specify the stream argument, otherwise the accesses within the inner form will be from the wrong object.

Example

This example is taken from real source. Note that the stream argument is specified, because there are 3 accesses here: one to grab the co-state slot, one to funcall the j-write-char function, and one to get the plist slot of the stream. All three access take one instruction each, after with-stream-class arranges for an extra variable to be pre-loaded with the instance slots vector of the stream.

(defmethod (setf stream-external-format)
    :after (external-format (stream single-channel-simple-stream))
  (with-stream-class (single-channel-simple-stream stream)
    (when (sm co-state stream)
      ;; stream has an ef writer state, flush ef here.
      (funcall-stm-handler-2 j-write-char nil stream))
    (single-channel-install-ef-methods
     stream external-format (getf (sm plist stream) 'access))))

This example demonstrates a nested with-stream-class. Note that the optional stream argument to the outer form isn't really necessary, but presumably a real-life situation would have more than one acesses to stream. Also, note that if the inner macro did not spocify a new optional stream argument (i.e. dribble), then the funcall-stm-handler-2 would have gotten its write-char handler from the wrong stream.

(defun do-a-dribble (stream char)
  (with-stream-class (dual-channel-simple-stream stream)
    (let ((dribble (sm dribble stream)))
       (when dribble
         (with-stream-class (stream dribble)
	   (funcall-stm-handler-2
	    j-write-char char dribble))))))

See streams.htm for information on the simple-streams implementation in Allegro CL.

The documentation is described in introduction.htm and the index is in index.htm.

Copyright (c) 1998-2000, Franz Inc. Berkeley, CA., USA. All rights reserved.

Created 2000.10.5.