[Pharo-users] Streams for FileReference in Pharo 7

Alistair Grant akgrant0710 at gmail.com
Sat Feb 16 11:46:37 EST 2019


On Sat, 16 Feb 2019 at 15:49, Sven Van Caekenberghe <sven at stfx.eu> wrote:
>
> > On 16 Feb 2019, at 14:35, Alistair Grant <akgrant0710 at gmail.com> wrote:
> >
> > Hi Sven & Jan,
> >
> > On Fri, 15 Feb 2019 at 10:25, Sven Van Caekenberghe <sven at stfx.eu> wrote:
> >>
> >> Hi Jan,
> >>
> >> I like #<< too, but I think your assumption that it can print anything on a stream is generally wrong, dangerous and unreliable.
> >>
> >> IMHO, you better stick to #print: in that case.
> >>
> >> Consider the follow, that all fail:
> >>
> >> String streamContents: [ :s | s << 'hello' << 42.5 << $! ].
> >>
> >> String streamContents: [ :s | s << 'hello' << (1 at 2) << $! ].
> >>
> >> In other words: #<< works in bizar ways (check the implementors of #putOn:).
> >>
> >> I would be inclined to change
> >>
> >> ZnEncodedStream>>#<< collection
> >>        ^ self nextPutAll: collection
> >>
> >> to
> >>
> >> ZnEncodedStream>>#<< collection
> >>        ^ self nextPutAll: collection asString
> >>
> >> but it would technically not be the same as the original #<< for in-memory streams.
> >>
> >> Opinions ?
> >
> > I've often thought that this change would be nice to have.  #putOn:
> > doesn't really fit in with writing to text streams (text in the loose
> > sense of "something that will be read").
> >
> > I think an argument could be made that #printString or #displayString
> > should be used, but they both have their own issues in practice.
> > So...
> >
> > +1 to "collection asString".
> >
> > Cheers,
> > Alistair
>
> I have been thinking a bit more about this, and I have a lot of problems with
>
> Integer>>#putOn: aStream
>         aStream isBinary
>                 ifTrue: [ self asByteArray do: [ :each | aStream nextPut: each ] ]
>                 ifFalse: [ self asString putOn: aStream ]
>
> I think we should simply remove this method. It is ugly and wrong.
>
> #<< should simply be a shortcut for either #nextPut: and #nextPutAll: and nothing more.
>
> The following two are OK for me:
>
>  String streamContents: [ :out | out << 'Hello' << $! ].
>  ByteArray streamContents: [ :out | out << #[ 1 2 3 ] << 4 ].
>
> But the following most definitively not:
>
>  (ByteArray streamContents: [ :out | out << 16rFF << 16rFF11 << 16rFFFF22 << 16rFFFFFF33 ]) hex.
>
> When you write out an integer, you have to decide its size, that can never depend on the magnitude (because there is no way to read this back unless there is additional bracketing).
>
> Also, printing to a stream should be (very) efficient. Making copies of objects just for conversion purposes should be avoided.
>
> I think that if we remove Integer>>#putOn: I could live with
>
>  ZnEncodedStream>>#<< anObject
>         anObject putOn: self
>
> The other solution is to define #<< as strictly the same as #nextPutAll: and remove all #putOn: implementors.

My thoughts aren't fully formed on this, but:

I think we can break the streams up in to three categories:

- Streams of arbitrary objects, i.e. streams writing to Arrays,
OrderedCollections, etc.
- Streams that serialise the objects, e.g. JSON, STON, ASN.1, etc.
- Streams that write to some form of text output intended for human reading.

We can then group the messages used by each category:

- Arbitrary object: nextPut:, nextPutAll:, putOn:, etc.
- Serialising: stonOn:, etc.
- Text: <<, cr, lf, etc.

Following these guidelines:

- I'd remove the Integer>>putOn: as you suggest.
- Add the #asString to ZnEncodedStream>><< as suggested earlier.

Cheers,
Alistair



More information about the Pharo-users mailing list