Default line endings while writing to a file stream
I'm on Windows wanting to write a text file with LF endings. The code developed on Linux is thus... (destinationDirectory / 'README.md') ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: class comment ] and I am stuck with CR line endings. The specific symptom is that it screws `git diff` Here is a simple experiment... testfile := 'README.md' asFileReference. testfile ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: 'aa bb' ]. testfile binaryReadStream contents at: 3 "==> Character cr " I think its safe to assume on Linux that will result in "==> Character lf " but can someone please confirm? So my issue is that I've got #ensureCreateFile - returns a FileReference and :stream - is a ZnCharacterWriteStream wrapping a ZnBufferedWriteStream wrapping BinaryFileStream. and neither seem to have an easily accessible defaultLineEnding setting. Indeed, line endings are not a property of FileReference and Binary & Characters have nothing to do with line endings, and questionable if Buffering is related. Its more a property of a File, but IIUC that is being deprecated (??) MultiByteFileStream has #lineEndConvention: but IIUC that also is being deprecated. So what is the proper way to force default line endings? ------ Now while composing this email I discovered String>>withUnixLineEndings. So I have a solution... testfile := 'README.md' asFileReference. testfile ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: 'aa bb' withUnixLineEndings ]. (testfile binaryReadStream contents at: 3) asCharacter "==> Character lf " but that seems to imply that on Windows... 'aa bb' at: 3 "==> Character cr " and on Linux (someone please confirm)... 'aa bb' at: 3 "==> Character lf " and that is *very* curious. Strange that I never noticed it before and obviously that hasn't hurt me, but considering the Principal Of Least Surprise it leaves me feeling somewhat violated :)
Ben, Inside the image, line endings are CR on all platforms (it would be a terrible mess if not). You want ZnNewlineWriterStream. It does the necessary translations, if you want that. HTH, Sven
On 31 May 2019, at 07:06, Ben Coman <btc@openinworld.com> wrote:
I'm on Windows wanting to write a text file with LF endings. The code developed on Linux is thus... (destinationDirectory / 'README.md') ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: class comment ]
and I am stuck with CR line endings. The specific symptom is that it screws `git diff` Here is a simple experiment... testfile := 'README.md' asFileReference. testfile ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: 'aa bb' ]. testfile binaryReadStream contents at: 3 "==> Character cr "
I think its safe to assume on Linux that will result in "==> Character lf " but can someone please confirm?
So my issue is that I've got #ensureCreateFile - returns a FileReference and :stream - is a ZnCharacterWriteStream wrapping a ZnBufferedWriteStream wrapping BinaryFileStream.
and neither seem to have an easily accessible defaultLineEnding setting. Indeed, line endings are not a property of FileReference and Binary & Characters have nothing to do with line endings, and questionable if Buffering is related.
Its more a property of a File, but IIUC that is being deprecated (??)
MultiByteFileStream has #lineEndConvention: but IIUC that also is being deprecated.
So what is the proper way to force default line endings?
------ Now while composing this email I discovered String>>withUnixLineEndings. So I have a solution... testfile := 'README.md' asFileReference. testfile ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: 'aa bb' withUnixLineEndings ]. (testfile binaryReadStream contents at: 3) asCharacter "==> Character lf "
but that seems to imply that on Windows... 'aa bb' at: 3 "==> Character cr "
and on Linux (someone please confirm)... 'aa bb' at: 3 "==> Character lf "
and that is *very* curious. Strange that I never noticed it before and obviously that hasn't hurt me, but considering the Principal Of Least Surprise it leaves me feeling somewhat violated :)
Itâs a great question with a few follow onâs... In github I think we can set it to ignore line endings for certain files (Iâm assuming this is Exercism), although Iâve noticed it doesnât seem to always work very well (could be the wrong settings thought. We should check we have .st set to text in that file. Similarly however, why is there a critic for line endings in methods? Anyone know what the big deal is? I world have thought we donât care? Tim Sent from my iPhone
On 31 May 2019, at 06:06, Ben Coman <btc@openinworld.com> wrote:
I'm on Windows wanting to write a text file with LF endings. The code developed on Linux is thus... (destinationDirectory / 'README.md') ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: class comment ]
and I am stuck with CR line endings. The specific symptom is that it screws `git diff` Here is a simple experiment... testfile := 'README.md' asFileReference. testfile ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: 'aa bb' ]. testfile binaryReadStream contents at: 3 "==> Character cr "
I think its safe to assume on Linux that will result in "==> Character lf " but can someone please confirm?
So my issue is that I've got #ensureCreateFile - returns a FileReference and :stream - is a ZnCharacterWriteStream wrapping a ZnBufferedWriteStream wrapping BinaryFileStream.
and neither seem to have an easily accessible defaultLineEnding setting. Indeed, line endings are not a property of FileReference and Binary & Characters have nothing to do with line endings, and questionable if Buffering is related.
Its more a property of a File, but IIUC that is being deprecated (??)
MultiByteFileStream has #lineEndConvention: but IIUC that also is being deprecated.
So what is the proper way to force default line endings?
------ Now while composing this email I discovered String>>withUnixLineEndings. So I have a solution... testfile := 'README.md' asFileReference. testfile ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: 'aa bb' withUnixLineEndings ]. (testfile binaryReadStream contents at: 3) asCharacter "==> Character lf "
but that seems to imply that on Windows... 'aa bb' at: 3 "==> Character cr "
and on Linux (someone please confirm)... 'aa bb' at: 3 "==> Character lf "
and that is *very* curious. Strange that I never noticed it before and obviously that hasn't hurt me, but considering the Principal Of Least Surprise it leaves me feeling somewhat violated :)
Hi Ben, On Fri, 31 May 2019 at 07:08, Ben Coman <btc@openinworld.com> wrote:
I'm on Windows wanting to write a text file with LF endings. The code developed on Linux is thus... (destinationDirectory / 'README.md') ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: class comment ]
I've come across this so many times that I always add a couple of methods to my image: ZnEncodedStream>>asNewLineStream "Answer the receiver wrapped with a ZnNewLineWriterStream" ^ZnNewLineWriterStream on: self! ! ZnNewLineWriterStream>>asNewLineStream "Answer the receiver wrapped with a ZnNewLineWriterStream" ^self! ! You could then modify the example above to be: stream asNewLineStream forLf nextPutAll: class comment Cheers, Alistair
and I am stuck with CR line endings. The specific symptom is that it screws `git diff` Here is a simple experiment... testfile := 'README.md' asFileReference. testfile ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: 'aa bb' ]. testfile binaryReadStream contents at: 3 "==> Character cr "
I think its safe to assume on Linux that will result in "==> Character lf " but can someone please confirm?
So my issue is that I've got #ensureCreateFile - returns a FileReference and :stream - is a ZnCharacterWriteStream wrapping a ZnBufferedWriteStream wrapping BinaryFileStream.
and neither seem to have an easily accessible defaultLineEnding setting. Indeed, line endings are not a property of FileReference and Binary & Characters have nothing to do with line endings, and questionable if Buffering is related.
Its more a property of a File, but IIUC that is being deprecated (??)
MultiByteFileStream has #lineEndConvention: but IIUC that also is being deprecated.
So what is the proper way to force default line endings?
------ Now while composing this email I discovered String>>withUnixLineEndings. So I have a solution... testfile := 'README.md' asFileReference. testfile ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: 'aa bb' withUnixLineEndings ]. (testfile binaryReadStream contents at: 3) asCharacter "==> Character lf "
but that seems to imply that on Windows... 'aa bb' at: 3 "==> Character cr "
and on Linux (someone please confirm)... 'aa bb' at: 3 "==> Character lf "
and that is *very* curious. Strange that I never noticed it before and obviously that hasn't hurt me, but considering the Principal Of Least Surprise it leaves me feeling somewhat violated :)
Sven why not having this as extension. Stef
On 2 Jun 2019, at 13:52, Alistair Grant <akgrant0710@gmail.com> wrote:
Hi Ben,
On Fri, 31 May 2019 at 07:08, Ben Coman <btc@openinworld.com> wrote:
I'm on Windows wanting to write a text file with LF endings. The code developed on Linux is thus... (destinationDirectory / 'README.md') ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: class comment ]
I've come across this so many times that I always add a couple of methods to my image:
ZnEncodedStream>>asNewLineStream "Answer the receiver wrapped with a ZnNewLineWriterStream" ^ZnNewLineWriterStream on: self! !
ZnNewLineWriterStream>>asNewLineStream "Answer the receiver wrapped with a ZnNewLineWriterStream" ^self! !
You could then modify the example above to be:
stream asNewLineStream forLf nextPutAll: class comment
Cheers, Alistair
and I am stuck with CR line endings. The specific symptom is that it screws `git diff` Here is a simple experiment... testfile := 'README.md' asFileReference. testfile ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: 'aa bb' ]. testfile binaryReadStream contents at: 3 "==> Character cr "
I think its safe to assume on Linux that will result in "==> Character lf " but can someone please confirm?
So my issue is that I've got #ensureCreateFile - returns a FileReference and :stream - is a ZnCharacterWriteStream wrapping a ZnBufferedWriteStream wrapping BinaryFileStream.
and neither seem to have an easily accessible defaultLineEnding setting. Indeed, line endings are not a property of FileReference and Binary & Characters have nothing to do with line endings, and questionable if Buffering is related.
Its more a property of a File, but IIUC that is being deprecated (??)
MultiByteFileStream has #lineEndConvention: but IIUC that also is being deprecated.
So what is the proper way to force default line endings?
------ Now while composing this email I discovered String>>withUnixLineEndings. So I have a solution... testfile := 'README.md' asFileReference. testfile ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: 'aa bb' withUnixLineEndings ]. (testfile binaryReadStream contents at: 3) asCharacter "==> Character lf "
but that seems to imply that on Windows... 'aa bb' at: 3 "==> Character cr "
and on Linux (someone please confirm)... 'aa bb' at: 3 "==> Character lf "
and that is *very* curious. Strange that I never noticed it before and obviously that hasn't hurt me, but considering the Principal Of Least Surprise it leaves me feeling somewhat violated :)
El 2 jun 2019, a las 20:45, ducasse <stepharo@netcourrier.com> escribió:
Sven
why not having this as extension.
Iâd even propose to have it by default: a FileReference writeStream can return a ZnNewLineWriterStream wrapping the corresponding stream. By default it can be configured with the systemâs default line ending convention (least surprise?). And then users can change it accordingly⦠Now I ask also myself what we could do when reading line endings from a file. Iâm 98.761% convinced that in the image we should have a single line ending convention for strings, and that we should convert internal strings to the external representation of convenience explicitly. In this direction we could make that default read streams in FileSystem to automatically transform external line endings into internal line endings.
Stef
On 2 Jun 2019, at 13:52, Alistair Grant <akgrant0710@gmail.com> wrote:
Hi Ben,
On Fri, 31 May 2019 at 07:08, Ben Coman <btc@openinworld.com> wrote:
I'm on Windows wanting to write a text file with LF endings. The code developed on Linux is thus... (destinationDirectory / 'README.md') ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: class comment ]
I've come across this so many times that I always add a couple of methods to my image:
ZnEncodedStream>>asNewLineStream "Answer the receiver wrapped with a ZnNewLineWriterStream" ^ZnNewLineWriterStream on: self! !
ZnNewLineWriterStream>>asNewLineStream "Answer the receiver wrapped with a ZnNewLineWriterStream" ^self! !
You could then modify the example above to be:
stream asNewLineStream forLf nextPutAll: class comment
Cheers, Alistair
and I am stuck with CR line endings. The specific symptom is that it screws `git diff` Here is a simple experiment... testfile := 'README.md' asFileReference. testfile ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: 'aa bb' ]. testfile binaryReadStream contents at: 3 "==> Character cr "
I think its safe to assume on Linux that will result in "==> Character lf " but can someone please confirm?
So my issue is that I've got #ensureCreateFile - returns a FileReference and :stream - is a ZnCharacterWriteStream wrapping a ZnBufferedWriteStream wrapping BinaryFileStream.
and neither seem to have an easily accessible defaultLineEnding setting. Indeed, line endings are not a property of FileReference and Binary & Characters have nothing to do with line endings, and questionable if Buffering is related.
Its more a property of a File, but IIUC that is being deprecated (??)
MultiByteFileStream has #lineEndConvention: but IIUC that also is being deprecated.
So what is the proper way to force default line endings?
------ Now while composing this email I discovered String>>withUnixLineEndings. So I have a solution... testfile := 'README.md' asFileReference. testfile ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: 'aa bb' withUnixLineEndings ]. (testfile binaryReadStream contents at: 3) asCharacter "==> Character lf "
but that seems to imply that on Windows... 'aa bb' at: 3 "==> Character cr "
and on Linux (someone please confirm)... 'aa bb' at: 3 "==> Character lf "
and that is *very* curious. Strange that I never noticed it before and obviously that hasn't hurt me, but considering the Principal Of Least Surprise it leaves me feeling somewhat violated :)
On 2 Jun 2019, at 21:24, Guillermo Polito <guillermopolito@gmail.com> wrote:
El 2 jun 2019, a las 20:45, ducasse <stepharo@netcourrier.com> escribió:
Sven
why not having this as extension.
Iâd even propose to have it by default: a FileReference writeStream can return a ZnNewLineWriterStream wrapping the corresponding stream. By default it can be configured with the systemâs default line ending convention (least surprise?). And then users can change it accordinglyâ¦
Now I ask also myself what we could do when reading line endings from a file. Iâm 98.761% convinced that in the image we should have a single line ending convention for strings, and that we should convert internal strings to the external representation of convenience explicitly. In this direction we could make that default read streams in FileSystem to automatically transform external line endings into internal line endings.
Maybe, maybe. It would still create the assumption that the standard stream has lots of functionality that you can automatically count on. Then it feels that we are back to where we started. The goal was to simplify, with simple, compose-able functionality. I know that the implementation would still be more or less modular, but many layers also carry a performance price. I feel like I am fighting a losing battle trying to simplify and clean up the stream API. The fact that we cannot use Traits is another problem, because inheritance does not cut it. See the old NILE project.
Stef
On 2 Jun 2019, at 13:52, Alistair Grant <akgrant0710@gmail.com> wrote:
Hi Ben,
On Fri, 31 May 2019 at 07:08, Ben Coman <btc@openinworld.com> wrote:
I'm on Windows wanting to write a text file with LF endings. The code developed on Linux is thus... (destinationDirectory / 'README.md') ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: class comment ]
I've come across this so many times that I always add a couple of methods to my image:
ZnEncodedStream>>asNewLineStream "Answer the receiver wrapped with a ZnNewLineWriterStream" ^ZnNewLineWriterStream on: self! !
ZnNewLineWriterStream>>asNewLineStream "Answer the receiver wrapped with a ZnNewLineWriterStream" ^self! !
You could then modify the example above to be:
stream asNewLineStream forLf nextPutAll: class comment
Cheers, Alistair
and I am stuck with CR line endings. The specific symptom is that it screws `git diff` Here is a simple experiment... testfile := 'README.md' asFileReference. testfile ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: 'aa bb' ]. testfile binaryReadStream contents at: 3 "==> Character cr "
I think its safe to assume on Linux that will result in "==> Character lf " but can someone please confirm?
So my issue is that I've got #ensureCreateFile - returns a FileReference and :stream - is a ZnCharacterWriteStream wrapping a ZnBufferedWriteStream wrapping BinaryFileStream.
and neither seem to have an easily accessible defaultLineEnding setting. Indeed, line endings are not a property of FileReference and Binary & Characters have nothing to do with line endings, and questionable if Buffering is related.
Its more a property of a File, but IIUC that is being deprecated (??)
MultiByteFileStream has #lineEndConvention: but IIUC that also is being deprecated.
So what is the proper way to force default line endings?
------ Now while composing this email I discovered String>>withUnixLineEndings. So I have a solution... testfile := 'README.md' asFileReference. testfile ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: 'aa bb' withUnixLineEndings ]. (testfile binaryReadStream contents at: 3) asCharacter "==> Character lf "
but that seems to imply that on Windows... 'aa bb' at: 3 "==> Character cr "
and on Linux (someone please confirm)... 'aa bb' at: 3 "==> Character lf "
and that is *very* curious. Strange that I never noticed it before and obviously that hasn't hurt me, but considering the Principal Of Least Surprise it leaves me feeling somewhat violated :)
I understand your point now this is about letting the guy specifying the line ending and this is really frequent.
Iâd even propose to have it by default: a FileReference writeStream can return a ZnNewLineWriterStream wrapping the corresponding stream. By default it can be configured with the systemâs default line ending convention (least surprise?). And then users can change it accordinglyâ¦
Now I ask also myself what we could do when reading line endings from a file. Iâm 98.761% convinced that in the image we should have a single line ending convention for strings, and that we should convert internal strings to the external representation of convenience explicitly. In this direction we could make that default read streams in FileSystem to automatically transform external line endings into internal line endings.
Maybe, maybe.
It would still create the assumption that the standard stream has lots of functionality that you can automatically count on. Then it feels that we are back to where we started.
The goal was to simplify, with simple, compose-able functionality.
I know that the implementation would still be more or less modular, but many layers also carry a performance price.
I feel like I am fighting a losing battle trying to simplify and clean up the stream API.
The fact that we cannot use Traits is another problem, because inheritance does not cut it. See the old NILE project.
Yes, maybe. These kind of convenience messages are cool, but it feels that many would be needed, and together they will form a heavy protocol by themselves, making it harder to implement a new stream from scratch.
On 2 Jun 2019, at 20:45, ducasse <stepharo@netcourrier.com> wrote:
Sven
why not having this as extension.
Stef
On 2 Jun 2019, at 13:52, Alistair Grant <akgrant0710@gmail.com> wrote:
Hi Ben,
On Fri, 31 May 2019 at 07:08, Ben Coman <btc@openinworld.com> wrote:
I'm on Windows wanting to write a text file with LF endings. The code developed on Linux is thus... (destinationDirectory / 'README.md') ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: class comment ]
I've come across this so many times that I always add a couple of methods to my image:
ZnEncodedStream>>asNewLineStream "Answer the receiver wrapped with a ZnNewLineWriterStream" ^ZnNewLineWriterStream on: self! !
ZnNewLineWriterStream>>asNewLineStream "Answer the receiver wrapped with a ZnNewLineWriterStream" ^self! !
You could then modify the example above to be:
stream asNewLineStream forLf nextPutAll: class comment
Cheers, Alistair
and I am stuck with CR line endings. The specific symptom is that it screws `git diff` Here is a simple experiment... testfile := 'README.md' asFileReference. testfile ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: 'aa bb' ]. testfile binaryReadStream contents at: 3 "==> Character cr "
I think its safe to assume on Linux that will result in "==> Character lf " but can someone please confirm?
So my issue is that I've got #ensureCreateFile - returns a FileReference and :stream - is a ZnCharacterWriteStream wrapping a ZnBufferedWriteStream wrapping BinaryFileStream.
and neither seem to have an easily accessible defaultLineEnding setting. Indeed, line endings are not a property of FileReference and Binary & Characters have nothing to do with line endings, and questionable if Buffering is related.
Its more a property of a File, but IIUC that is being deprecated (??)
MultiByteFileStream has #lineEndConvention: but IIUC that also is being deprecated.
So what is the proper way to force default line endings?
------ Now while composing this email I discovered String>>withUnixLineEndings. So I have a solution... testfile := 'README.md' asFileReference. testfile ensureCreateFile writeStreamDo: [ :stream | stream nextPutAll: 'aa bb' withUnixLineEndings ]. (testfile binaryReadStream contents at: 3) asCharacter "==> Character lf "
but that seems to imply that on Windows... 'aa bb' at: 3 "==> Character cr "
and on Linux (someone please confirm)... 'aa bb' at: 3 "==> Character lf "
and that is *very* curious. Strange that I never noticed it before and obviously that hasn't hurt me, but considering the Principal Of Least Surprise it leaves me feeling somewhat violated :)
participants (6)
-
Alistair Grant -
Ben Coman -
ducasse -
Guillermo Polito -
Sven Van Caekenberghe -
Tim Mackinnon