I am playing around with Zinc, and I get an
"Error - Improper store into indexable object” at ZnBufferedWriteStream>>nextPut: My Workspace: ----- | response | response := ZnClient new url:'http://amazon.com'; get; response. response writeOn: Transcript. Transcript flush ----- The reason is that instead of a Character, there is a SmallInteger of value 10 being added at ByteString>>at:put: (and 10 is a linefeed). Also the string in the entity is a WideString (ZnUTF8Encoder>>next:putAll:startingAt:toStream is where the choice is made to decode a ByteString vs WideString). Is this a bug? Running on Pharo 3. My newb debugging skills don’t go further :( Other sites that fail are reddit.com, news.ycombinator.com. Thanks, -Ed |
Hi Edward,
> On 29 Dec 2014, at 17:19, Edward Povazan <[hidden email]> wrote: > > I am playing around with Zinc, and I get an > "Error - Improper store into indexable object” > at > ZnBufferedWriteStream>>nextPut: > > My Workspace: > ----- > | response | > response := ZnClient new > url:'http://amazon.com'; > get; > response. > > response writeOn: Transcript. > Transcript flush > ----- > > The reason is that instead of a Character, there is a SmallInteger of value 10 being added at ByteString>>at:put: (and 10 is a linefeed). > > Also the string in the entity is a WideString (ZnUTF8Encoder>>next:putAll:startingAt:toStream is where the choice is made to decode a ByteString vs WideString). > > Is this a bug? Running on Pharo 3. My newb debugging skills don’t go further :( Other sites that fail are reddit.com, news.ycombinator.com. > > Thanks, > -Ed Short answer: Zinc writes to or reads from binary streams, the Transcript is a character stream. I know that what you are trying to do is actually in the documentation and in the API, and it normally works, just not in all cases. It is better to use inspection to look at what is going on, you'll get a much more structured (object-oriented) view of what is going on. I would suggest inspecting the ZnClient instance, which will hold the state of the last request and response. Long answer: If you try | response | response := ZnClient new url:'http://stfx.eu/small.html'; get; response. response writeToTranscript. It will work and print HTTP/1.1 200 OK X-Pad: avoid browser bug Date: Mon, 29 Dec 2014 18:56:37 GMT Content-Length: 113 Etag: "202f9-71-4c7ae94364f1e" Server: Apache/2.2.22 (Ubuntu) Accept-Ranges: bytes Last-Modified: Mon, 20 Aug 2012 08:48:51 GMT Vary: Accept-Encoding Content-Type: text/html <html> <head><title>Small</title></head> <body><h1>Small</h1><p>This is a small HTML document</p></body> </html> So what is the difference ? The fact that the responses that you get from the website you mention are using chunked transfer encoding (http://en.wikipedia.org/wiki/Chunked_transfer_encoding). Zinc deals with this in both ways, while reading a response, but also while writing a response (which is what you are trying to do here). Here is how you disable chunked transfer encoding so that you can write the response to the Transcript | response | response := ZnClient new url:'http://amazon.com'; get; response. response headers removeKey: 'Transfer-Encoding'. response writeToTranscript. Zinc manages to write to the Transcript in most cases by cheating a bit: it wraps a ZnBivalentWriteStream around another stream when needed - such a stream can do both binary and character writing at the same time (though the result is only good for quick and dirty debugging, since it is not 100% correct). I hope the long explanation didn't make it worse ;-) HTH, Sven PS: BTW, in Pharo 4 with Zinc #bleedingEdge you get even nicer and more high level presentations of Zinc objects in GT-Inspector ! |
> On 29 Dec 2014, at 20:16, Sven Van Caekenberghe <[hidden email]> wrote: > > Hi Edward, > >> On 29 Dec 2014, at 17:19, Edward Povazan <[hidden email]> wrote: >> >> I am playing around with Zinc, and I get an >> "Error - Improper store into indexable object” >> at >> ZnBufferedWriteStream>>nextPut: >> >> My Workspace: >> ----- >> | response | >> response := ZnClient new >> url:'http://amazon.com'; >> get; >> response. >> >> response writeOn: Transcript. >> Transcript flush >> ----- >> >> The reason is that instead of a Character, there is a SmallInteger of value 10 being added at ByteString>>at:put: (and 10 is a linefeed). >> >> Also the string in the entity is a WideString (ZnUTF8Encoder>>next:putAll:startingAt:toStream is where the choice is made to decode a ByteString vs WideString). >> >> Is this a bug? Running on Pharo 3. My newb debugging skills don’t go further :( Other sites that fail are reddit.com, news.ycombinator.com. >> >> Thanks, >> -Ed > > Short answer: > > Zinc writes to or reads from binary streams, the Transcript is a character stream. I know that what you are trying to do is actually in the documentation and in the API, and it normally works, just not in all cases. It is better to use inspection to look at what is going on, you'll get a much more structured (object-oriented) view of what is going on. I would suggest inspecting the ZnClient instance, which will hold the state of the last request and response. > > Long answer: > > If you try > > | response | > response := ZnClient new > url:'http://stfx.eu/small.html'; > get; > response. > > response writeToTranscript. > > It will work and print > > HTTP/1.1 200 OK > X-Pad: avoid browser bug > Date: Mon, 29 Dec 2014 18:56:37 GMT > Content-Length: 113 > Etag: "202f9-71-4c7ae94364f1e" > Server: Apache/2.2.22 (Ubuntu) > Accept-Ranges: bytes > Last-Modified: Mon, 20 Aug 2012 08:48:51 GMT > Vary: Accept-Encoding > Content-Type: text/html > > <html> > <head><title>Small</title></head> > <body><h1>Small</h1><p>This is a small HTML document</p></body> > </html> > > So what is the difference ? > > The fact that the responses that you get from the website you mention are using chunked transfer encoding (http://en.wikipedia.org/wiki/Chunked_transfer_encoding). Zinc deals with this in both ways, while reading a response, but also while writing a response (which is what you are trying to do here). > > Here is how you disable chunked transfer encoding so that you can write the response to the Transcript > > | response | > response := ZnClient new > url:'http://amazon.com'; > get; > response. > > response headers removeKey: 'Transfer-Encoding'. > response writeToTranscript. > > Zinc manages to write to the Transcript in most cases by cheating a bit: it wraps a ZnBivalentWriteStream around another stream when needed - such a stream can do both binary and character writing at the same time (though the result is only good for quick and dirty debugging, since it is not 100% correct). I forgot to add that in the case of chunked transfer encoding, the bivalent property of the output stream gets lost because it gets wrapped in both a ZnChunkedWriteStream and a ZnBufferedWriteStream. > I hope the long explanation didn't make it worse ;-) > > HTH, > > Sven > > PS: BTW, in Pharo 4 with Zinc #bleedingEdge you get even nicer and more high level presentations of Zinc objects in GT-Inspector ! > |
In reply to this post by Sven Van Caekenberghe-2
Sven, thank you so much for the detailed explanation.
I used it to look at the debugger again so I could reformulate the way I look for bugs. I’d was looking backwards from the error, but had I started at the DoIt, I would have seen the ZnBivalentWriteStream and seen the class comment. Moreover, I would have realized it all starts with the Transcript. I guess habits from my other environment (iOS, where the stack leads into closed source). And here in Pharo I can inspect the MethodContext and see the program counter :) Thanks again, -Edward > On Dec 29, 2014, at 11:16 AM, Sven Van Caekenberghe <[hidden email]> wrote: > > Hi Edward, > >> On 29 Dec 2014, at 17:19, Edward Povazan <[hidden email]> wrote: >> >> I am playing around with Zinc, and I get an >> "Error - Improper store into indexable object” >> at >> ZnBufferedWriteStream>>nextPut: >> >> My Workspace: >> ----- >> | response | >> response := ZnClient new >> url:'http://amazon.com'; >> get; >> response. >> >> response writeOn: Transcript. >> Transcript flush >> ----- >> >> The reason is that instead of a Character, there is a SmallInteger of value 10 being added at ByteString>>at:put: (and 10 is a linefeed). >> >> Also the string in the entity is a WideString (ZnUTF8Encoder>>next:putAll:startingAt:toStream is where the choice is made to decode a ByteString vs WideString). >> >> Is this a bug? Running on Pharo 3. My newb debugging skills don’t go further :( Other sites that fail are reddit.com, news.ycombinator.com. >> >> Thanks, >> -Ed > > Short answer: > > Zinc writes to or reads from binary streams, the Transcript is a character stream. I know that what you are trying to do is actually in the documentation and in the API, and it normally works, just not in all cases. It is better to use inspection to look at what is going on, you'll get a much more structured (object-oriented) view of what is going on. I would suggest inspecting the ZnClient instance, which will hold the state of the last request and response. > > Long answer: > > If you try > > | response | > response := ZnClient new > url:'http://stfx.eu/small.html'; > get; > response. > > response writeToTranscript. > > It will work and print > > HTTP/1.1 200 OK > X-Pad: avoid browser bug > Date: Mon, 29 Dec 2014 18:56:37 GMT > Content-Length: 113 > Etag: "202f9-71-4c7ae94364f1e" > Server: Apache/2.2.22 (Ubuntu) > Accept-Ranges: bytes > Last-Modified: Mon, 20 Aug 2012 08:48:51 GMT > Vary: Accept-Encoding > Content-Type: text/html > > <html> > <head><title>Small</title></head> > <body><h1>Small</h1><p>This is a small HTML document</p></body> > </html> > > So what is the difference ? > > The fact that the responses that you get from the website you mention are using chunked transfer encoding (http://en.wikipedia.org/wiki/Chunked_transfer_encoding). Zinc deals with this in both ways, while reading a response, but also while writing a response (which is what you are trying to do here). > > Here is how you disable chunked transfer encoding so that you can write the response to the Transcript > > | response | > response := ZnClient new > url:'http://amazon.com'; > get; > response. > > response headers removeKey: 'Transfer-Encoding'. > response writeToTranscript. > > Zinc manages to write to the Transcript in most cases by cheating a bit: it wraps a ZnBivalentWriteStream around another stream when needed - such a stream can do both binary and character writing at the same time (though the result is only good for quick and dirty debugging, since it is not 100% correct). > > I hope the long explanation didn't make it worse ;-) > > HTH, > > Sven > > PS: BTW, in Pharo 4 with Zinc #bleedingEdge you get even nicer and more high level presentations of Zinc objects in GT-Inspector ! > > |
In reply to this post by Sven Van Caekenberghe-2
Sven
this is a really cool answer! May be we should add that somewhere :) Stef Le 29/12/14 20:16, Sven Van Caekenberghe a écrit : > Hi Edward, > >> On 29 Dec 2014, at 17:19, Edward Povazan <[hidden email]> wrote: >> >> I am playing around with Zinc, and I get an >> "Error - Improper store into indexable object” >> at >> ZnBufferedWriteStream>>nextPut: >> >> My Workspace: >> ----- >> | response | >> response := ZnClient new >> url:'http://amazon.com'; >> get; >> response. >> >> response writeOn: Transcript. >> Transcript flush >> ----- >> >> The reason is that instead of a Character, there is a SmallInteger of value 10 being added at ByteString>>at:put: (and 10 is a linefeed). >> >> Also the string in the entity is a WideString (ZnUTF8Encoder>>next:putAll:startingAt:toStream is where the choice is made to decode a ByteString vs WideString). >> >> Is this a bug? Running on Pharo 3. My newb debugging skills don’t go further :( Other sites that fail are reddit.com, news.ycombinator.com. >> >> Thanks, >> -Ed > Short answer: > > Zinc writes to or reads from binary streams, the Transcript is a character stream. I know that what you are trying to do is actually in the documentation and in the API, and it normally works, just not in all cases. It is better to use inspection to look at what is going on, you'll get a much more structured (object-oriented) view of what is going on. I would suggest inspecting the ZnClient instance, which will hold the state of the last request and response. > > Long answer: > > If you try > > | response | > response := ZnClient new > url:'http://stfx.eu/small.html'; > get; > response. > > response writeToTranscript. > > It will work and print > > HTTP/1.1 200 OK > X-Pad: avoid browser bug > Date: Mon, 29 Dec 2014 18:56:37 GMT > Content-Length: 113 > Etag: "202f9-71-4c7ae94364f1e" > Server: Apache/2.2.22 (Ubuntu) > Accept-Ranges: bytes > Last-Modified: Mon, 20 Aug 2012 08:48:51 GMT > Vary: Accept-Encoding > Content-Type: text/html > > <html> > <head><title>Small</title></head> > <body><h1>Small</h1><p>This is a small HTML document</p></body> > </html> > > So what is the difference ? > > The fact that the responses that you get from the website you mention are using chunked transfer encoding (http://en.wikipedia.org/wiki/Chunked_transfer_encoding). Zinc deals with this in both ways, while reading a response, but also while writing a response (which is what you are trying to do here). > > Here is how you disable chunked transfer encoding so that you can write the response to the Transcript > > | response | > response := ZnClient new > url:'http://amazon.com'; > get; > response. > > response headers removeKey: 'Transfer-Encoding'. > response writeToTranscript. > > Zinc manages to write to the Transcript in most cases by cheating a bit: it wraps a ZnBivalentWriteStream around another stream when needed - such a stream can do both binary and character writing at the same time (though the result is only good for quick and dirty debugging, since it is not 100% correct). > > I hope the long explanation didn't make it worse ;-) > > HTH, > > Sven > > PS: BTW, in Pharo 4 with Zinc #bleedingEdge you get even nicer and more high level presentations of Zinc objects in GT-Inspector ! > > > |
Free forum by Nabble | Edit this page |