[Pharo-users] Stream >> <<

Herby Vojčík herby at mailbox.sk
Tue Sep 10 11:27:13 EDT 2019


On 10. 9. 2019 15:20, Sven Van Caekenberghe wrote:
> Development happens in Pharo 8 first, with possible back ports if really necessary.
> 
> The last relevant change was the following:
> 
> https://github.com/pharo-project/pharo/pull/2698
> 
That's a very nice change, indeed. Thank you.

But there's still one catch. I looked, and in Pharo 8 branch, this is 
still the active implementation:

WriteStream >> << anObject [
	"Write anObject to the receiver, dispatching using #putOn:
	This is a shortcut for both nextPut: and nextPutAll: since anObject can 
be both
	the element type of the receiver as well as a collection of those elements.
	No further conversions of anObject are applied.
	This is an optimisation.
	Return self to accomodate chaining."

  	anObject class == collection class
		ifTrue: [ self nextPutAll: anObject ]
		ifFalse: [ anObject putOn: self ]
]

It is wrong to shortcut putOn: double dispatch based on anObject class 
== collection class. I strongly believe this test should pass:

testPutDiverseNestedSequences

   | array otherSequenceable higherOrderArray higherOrderSequenceable |

   array := Array with: 1 with: 2 with: 3.
   otherSequenceable := OrderedCollection with: 1 with: 2 with: 3.
   higherOrderArray := Array with: array with: otherSequenceable.
   higherOrderSequenceable := OrderedCollection with: array with: 
otherSequenceable.

   result := Array streamContents: [ :s | s
     << array << otherSequenceable
     << higherOrderArray << higherOrderSequenceable ].

   self assert: result equals: #(
     1 2 3 1 2 3
     1 2 3 1 2 3
     1 2 3 1 2 3 )

If I guess correctly, based on mere implemetation detail of which class 
holds the 1 2 3, some of them are not unnested.

I understand how that optimization is needed in case a string is put on 
character stream, double dispatching every character is insane. But so 
is shortcutting Array is Array-based stream.

Maybe the optimization should have additional anObject isString test (in 
case of string, the counterexample cannot be created, because they 
cannot be nested). Or there should be additional double dispatch via 
nextPutString:, if string-based streams have their hierarchy. You know 
the codebase better.

Unless it is already solved by some other twist.

Thanks, Herby



More information about the Pharo-users mailing list