inconsistency PositionableStream>>#position: between Pharo and Gemstone

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|

inconsistency PositionableStream>>#position: between Pharo and Gemstone

Nick
Hi,

The following test runs fine in Pharo:

testPosition
| emptyStream |
emptyStream := WriteStream on: String new.
emptyStream position: 0.
self assert: (emptyStream contents = '')

but in Gemstone generates the error:

"An attempt was made to set the stream aWriteStream to position 0 beyond the limits of the collection"

In the Pharo the implementation reads:

PositionableStream>>position: anInteger 
"Set the current position for accessing the objects to be anInteger, as long 
as anInteger is within the bounds of the receiver's contents. If it is not, 
create an error notification."

(anInteger >= 0 and: [anInteger <= readLimit])
ifTrue: [position := anInteger]
ifFalse: [self positionError]


Gemstone's implementation is:

PositionableStream>>position: anInteger

"Sets the receiver's current position reference for accessing the collection to
 be anInteger.  If anInteger is not within the bounds of the collection,
 generates an error.
 
 This is the 'Legacy' (non-ANSI) method. See Bug #39503."

(anInteger > 0) & (anInteger <= (itsCollection size + 1))
   ifTrue: [position := anInteger]
   ifFalse: [self _positionError: anInteger]

Anyone any ideas if it is a Pharo or Gemstone bug?

Cheers

Nick
Reply | Threaded
Open this post in threaded view
|

Re: inconsistency PositionableStream>>#position: between Pharo and Gemstone

Nick
I naively thought simply changing the check in #position from #> to #>= 0 would provide a temporary fix. However #atEnd then doesn't report true. An updated test case is:


testPosition
| emptyStream |
emptyStream := WriteStream on: String new.
emptyStream position: 0.
self assert: (emptyStream atEnd).
self assert: (emptyStream contents = '')



On 26 October 2010 11:13, Nick Ager <[hidden email]> wrote:
Hi,

The following test runs fine in Pharo:

testPosition
| emptyStream |
emptyStream := WriteStream on: String new.
emptyStream position: 0.
self assert: (emptyStream contents = '')

but in Gemstone generates the error:

"An attempt was made to set the stream aWriteStream to position 0 beyond the limits of the collection"

In the Pharo the implementation reads:

PositionableStream>>position: anInteger 
"Set the current position for accessing the objects to be anInteger, as long 
as anInteger is within the bounds of the receiver's contents. If it is not, 
create an error notification."

(anInteger >= 0 and: [anInteger <= readLimit])
ifTrue: [position := anInteger]
ifFalse: [self positionError]


Gemstone's implementation is:

PositionableStream>>position: anInteger

"Sets the receiver's current position reference for accessing the collection to
 be anInteger.  If anInteger is not within the bounds of the collection,
 generates an error.
 
 This is the 'Legacy' (non-ANSI) method. See Bug #39503."

(anInteger > 0) & (anInteger <= (itsCollection size + 1))
   ifTrue: [position := anInteger]
   ifFalse: [self _positionError: anInteger]

Anyone any ideas if it is a Pharo or Gemstone bug?

Cheers

Nick

Reply | Threaded
Open this post in threaded view
|

Re: inconsistency PositionableStream>>#position: between Pharo and Gemstone

Mariano Martinez Peck
maybe it is worth adding such test to Grease or something like that?


On Tue, Oct 26, 2010 at 1:31 PM, Nick Ager <[hidden email]> wrote:
I naively thought simply changing the check in #position from #> to #>= 0 would provide a temporary fix. However #atEnd then doesn't report true. An updated test case is:


testPosition
| emptyStream |
emptyStream := WriteStream on: String new.
emptyStream position: 0.
self assert: (emptyStream atEnd).
self assert: (emptyStream contents = '')



On 26 October 2010 11:13, Nick Ager <[hidden email]> wrote:
Hi,

The following test runs fine in Pharo:

testPosition
| emptyStream |
emptyStream := WriteStream on: String new.
emptyStream position: 0.
self assert: (emptyStream contents = '')

but in Gemstone generates the error:

"An attempt was made to set the stream aWriteStream to position 0 beyond the limits of the collection"

In the Pharo the implementation reads:

PositionableStream>>position: anInteger 
"Set the current position for accessing the objects to be anInteger, as long 
as anInteger is within the bounds of the receiver's contents. If it is not, 
create an error notification."

(anInteger >= 0 and: [anInteger <= readLimit])
ifTrue: [position := anInteger]
ifFalse: [self positionError]


Gemstone's implementation is:

PositionableStream>>position: anInteger

"Sets the receiver's current position reference for accessing the collection to
 be anInteger.  If anInteger is not within the bounds of the collection,
 generates an error.
 
 This is the 'Legacy' (non-ANSI) method. See Bug #39503."

(anInteger > 0) & (anInteger <= (itsCollection size + 1))
   ifTrue: [position := anInteger]
   ifFalse: [self _positionError: anInteger]

Anyone any ideas if it is a Pharo or Gemstone bug?

Cheers

Nick


Reply | Threaded
Open this post in threaded view
|

Re: inconsistency PositionableStream>>#position: between Pharo and Gemstone

Udo Schneider
In reply to this post by Nick
Nick,

as far as I read through the docs I think that's due to a difference in Stream positioning between GS and "ANSI Smalltalk".

ANSI states that streams are 0-based. GS on the other hand is 1-based by default.

You can change the behavior using:
Globals at: #'PositionableStream_position' put: #'ANSI'.
PositionableStream compilePositionMethods.

All the details are also in the GS Programming Guide. Search for "Position and ANSI" (p. 94 in my PDF).

CU,

Udo



On 26.10.2010, at 13:31, Nick Ager wrote:

I naively thought simply changing the check in #position from #> to #>= 0 would provide a temporary fix. However #atEnd then doesn't report true. An updated test case is:


testPosition
| emptyStream |
emptyStream := WriteStream on: String new.
emptyStream position: 0.
self assert: (emptyStream atEnd).
self assert: (emptyStream contents = '')



On 26 October 2010 11:13, Nick Ager <[hidden email]> wrote:
Hi,

The following test runs fine in Pharo:

testPosition
| emptyStream |
emptyStream := WriteStream on: String new.
emptyStream position: 0.
self assert: (emptyStream contents = '')

but in Gemstone generates the error:

"An attempt was made to set the stream aWriteStream to position 0 beyond the limits of the collection"

In the Pharo the implementation reads:

PositionableStream>>position: anInteger 
"Set the current position for accessing the objects to be anInteger, as long 
as anInteger is within the bounds of the receiver's contents. If it is not, 
create an error notification."

(anInteger >= 0 and: [anInteger <= readLimit])
ifTrue: [position := anInteger]
ifFalse: [self positionError]


Gemstone's implementation is:

PositionableStream>>position: anInteger

"Sets the receiver's current position reference for accessing the collection to
 be anInteger.  If anInteger is not within the bounds of the collection,
 generates an error.
 
 This is the 'Legacy' (non-ANSI) method. See Bug #39503."

(anInteger > 0) & (anInteger <= (itsCollection size + 1))
   ifTrue: [position := anInteger]
   ifFalse: [self _positionError: anInteger]

Anyone any ideas if it is a Pharo or Gemstone bug?

Cheers

Nick


Reply | Threaded
Open this post in threaded view
|

Re: inconsistency PositionableStream>>#position: between Pharo and Gemstone

Dale Henrichs
In reply to this post by Nick
Nick,

GemStone streams are not ANSI compliant ... it is something that we will
fix in GemStone 3.0 (I hope). For Seaside3.0/Grease I have added three
classes: AnsiReadStream, AnsiWriteStream, and AnsiReadWriteStream. The
internals haven't changed, but the semantics of #position and #position:
_are_ ANSI compliant ...

If you are subclassing or porting subclasses, there is potentially a
fair amount of work involved, since GemStone doesn't have the #readLimit
and #writeLimit instance variables and the collection instance variable
is named #itsCollection ...

Dale

On 10/26/2010 03:13 AM, Nick Ager wrote:

> Hi,
>
> The following test runs fine in Pharo:
>
>     testPosition
>
>     | emptyStream |
>
>     emptyStream := WriteStream on: String new.
>
>     emptyStream position: 0.
>
>     self assert: (emptyStream contents = '')
>
>
> but in Gemstone generates the error:
>
>     "An attempt was made to set the stream aWriteStream to position 0
>     beyond the limits of the collection"
>
>
> In the Pharo the implementation reads:
>
>     PositionableStream>>position: anInteger
>
>     "Set the current position for accessing the objects to be anInteger,
>     as long
>
>     as anInteger is within the bounds of the receiver's contents. If it
>     is not,
>
>     create an error notification."
>
>
>     (anInteger >= 0 and: [anInteger <= readLimit])
>
>     ifTrue: [position := anInteger]
>
>     ifFalse: [self positionError]
>
>
>
> Gemstone's implementation is:
>
>     PositionableStream>>position: anInteger
>
>
>     "Sets the receiver's current position reference for accessing the
>     collection to
>
>       be anInteger.  If anInteger is not within the bounds of the
>     collection,
>
>       generates an error.
>
>       This is the 'Legacy' (non-ANSI) method. See Bug #39503."
>
>
>     (anInteger > 0) & (anInteger <= (itsCollection size + 1))
>
>         ifTrue: [position := anInteger]
>
>         ifFalse: [self _positionError: anInteger]
>
>
> Anyone any ideas if it is a Pharo or Gemstone bug?
>
> Cheers
>
> Nick

Reply | Threaded
Open this post in threaded view
|

Re: inconsistency PositionableStream>>#position: between Pharo and Gemstone

Philippe Marschall
In reply to this post by Mariano Martinez Peck
2010/10/26 Mariano Martinez Peck <[hidden email]>:
> maybe it is worth adding such test to Grease or something like that?

There is actually #readWriteByteStream and #readWriteCharacterStream
on platform.

Cheers
Philippe
Reply | Threaded
Open this post in threaded view
|

Re: inconsistency PositionableStream>>#position: between Pharo and Gemstone

Nick
In reply to this post by Udo Schneider
Hi,

You can change the behavior using:
Globals at: #'PositionableStream_position' put: #'ANSI'.
PositionableStream compilePositionMethods.

All the details are also in the GS Programming Guide. Search for "Position and ANSI" (p. 94 in my PDF).

Has anyone set this ANSI compatible flag within their Gemstone/Seaside projects? Looking at senders of #position: and #position I'm not clear whether there would be unintended side-effects either way. 

Any thoughts or experience from the trenches?

Nick
Reply | Threaded
Open this post in threaded view
|

Re: inconsistency PositionableStream>>#position: between Pharo and Gemstone

Dale Henrichs
On 10/26/2010 11:56 AM, Nick Ager wrote:

> Hi,
>
>     You can change the behavior using:
>     Globals at: #'PositionableStream_position' put: #'ANSI'.
>     PositionableStream compilePositionMethods.
>
>     All the details are also in the GS Programming Guide. Search for
>     "Position and ANSI" (p. 94 in my PDF).
>
>
> Has anyone set this ANSI compatible flag within their Gemstone/Seaside
> projects? Looking at senders of #position: and #position I'm not clear
> whether there would be unintended side-effects either way.
>
> Any thoughts or experience from the trenches?
>
> Nick

I don't recommend doing that ... use the Ansi* classes that I mentioned
earlier for ANSI behavior. If you switch the methods at the level of
PositionableStream, you will certainly get ANSI behavior, but it will
break existing GLASS stream implementations like the zip streams used in
Monticello...

Dale


Reply | Threaded
Open this post in threaded view
|

Re: inconsistency PositionableStream>>#position: between Pharo and Gemstone

Dale Henrichs
In reply to this post by Philippe Marschall
On 10/26/2010 11:53 AM, Philippe Marschall wrote:
> 2010/10/26 Mariano Martinez Peck<[hidden email]>:
>> maybe it is worth adding such test to Grease or something like that?
>
> There is actually #readWriteByteStream and #readWriteCharacterStream
> on platform.
>
> Cheers
> Philippe

Yes, I neglected to mention that if you use the Grease API for getting
your streams, you will get the ANSI streams and the ANSI behavior ...
with the benefit of having something that works on both Pharo and
GemStone ...

Dale