Without getting into a general debate about the new stream classes,
a stream class meant for writing to a file SHOULDN'T have #contents
in its interface.

(1) For example, if you open a channel for *output* in Unix, you have
no reason to expect that you have been granted a right to read it.
For example, suppose user=fred group=whizzy owns a file foo.grace
with permission bits rw--w---- and you are running a program as
user=mary group=whizzy.  You can open foo.grace for writing, but
you cannot read it.
(2) The thing you open might not be a file.  It might be, for
example, a symbolic link to /dev/null, a symbolic link to /dev/tty,
a named pipe, or even (in principle, I don't know if anyone has
done it, but with something like FUSE it *could* be done) a socket
to a remote machine.  In all these cases, *nobody* is storing the
contents.
(3) If the thing you open *is* a disc file, and you *do* have
permission to read it back, what should happen if you have written
more to the file than your memory can hold?

If you know that the output written to the stream is going to be
small enough that holding it in memory won't be a problem, could
you use a WriteStream and then write it to the output file in one
burst when it's finished?

Now, what about #ensureASpace?  It can *almost* be done on a
buffered stream by looking at the last character in the buffer
and adding a space if it isn't one.  But what if you called
#flush and the buffer is empty?  Well, in that case, if you have
a "monolithic" design where the stream records the last character
at every flush, it's still doable.  If you don't have a monolithic
design, you have to be able to read the last block before the
present one, and we've just seen why that is not in general
possible.  The one thing you can safely do is to say that if the
buffer is empty you will add a space just to be sure, so that the
contract for #ensureASpace becomes
   Ensures that the past contents of the receiver ends with a
   space.  Tries to avoid adding a space when there is already
   one, but may or may not succeed.


On 1 August 2018 at 10:34, Andrew P. Black <[email protected]> wrote:

> I’m making a stream to write on a file using
>
>         outputFile := FileLocator home / 'Desktop' / classBeingTranslated
> name , '.grace'.
>         outputFile writeStreamDo: [ :s |  ... ]
>
> Is that OK?   When I do the above, in the writeStreamDo: block,  s is
> bound to an instance of  ZnCharacterWriteStream.    But that class does nt
> understand many methods from WriteStream.  For example, #contents is not
> understood, and nor is #ensureASpace.
>
> To put things another way: I wrote tests using a stream created with
> String streamContents: [ :s | ... ], and everything worked fine.   Then,
> for production use, I switch to a stream created using outputFile
> writeStreamDo: [ :s | ... ] and everything breaks.
>
> I know that ZnCharacterWriteStream is fairly new.  Am I doing something
> wrong, or is ZnCharacterWriteStream still under development?
>
>         Andrew
>
>
>

Reply via email to