[Pharo-project] about ensuring file closing
Hi I would like to get your thoughts on the following: Following the blog of ramon and his code in sandstoneDB which extends dataStream as follows: Here is a typical example: fileNamed: aName do: aBlock | file | file := self fileNamed: aName. ^ file ifNil: [ nil ] ifNotNil: [ [ aBlock value: file ] ensure: [ file close ] ] fileNamed: aString "Here is the way to use DataStream and ReferenceStream: rr := ReferenceStream fileNamed: 'test.obj'. rr nextPut: <your object>. rr close. better use: fileNamed:do: " | strm | strm := self on: (FileStream fileNamed: aString). "will be binary" strm byteStream setFileTypeToObject. "Type and Creator not to be text, so can attach correctly to an email msg" ^ strm There is similar pattern in FileStream detectFile: aBlock do: anotherBlock | file | file := aBlock value. ^ file ifNil: [ nil ] ifNotNil: [ [anotherBlock value: file] ensure: [file close]] fileNamed: fileName ^ self concreteStream fileNamed: (self fullName: fileName) fileNamed: fileName do: aBlock "Avi Bryant says, ''This idiom is quite common in other languages that make heavy use of closures (i.e. Lisp (with-file 'foo' (f) ...) and Ruby (File.open('foo'){| f|...})). It's time Squeak had it, too.'' Returns the result of aBlock." ^ self detectFile: [ self fileNamed: fileName ] do: aBlock I have a question: - would not be better to even wrap the on: into the first block of the ensure: message? - do we have to close a file even if its creation failed? Stef
On Tue, 2008-07-15 at 15:26 +0200, Stéphane Ducasse wrote:
Hi
I would like to get your thoughts on the following:
Following the blog of ramon and his code in sandstoneDB which extends dataStream as follows:
Here is a typical example:
fileNamed: aName do: aBlock | file | file := self fileNamed: aName. ^ file ifNil: [ nil ] ifNotNil: [ [ aBlock value: file ] ensure: [ file close ] ]
fileNamed: aString "Here is the way to use DataStream and ReferenceStream: rr := ReferenceStream fileNamed: 'test.obj'. rr nextPut: <your object>. rr close. better use: fileNamed:do: "
| strm | strm := self on: (FileStream fileNamed: aString). "will be binary" strm byteStream setFileTypeToObject. "Type and Creator not to be text, so can attach correctly to an email msg" ^ strm
There is similar pattern in FileStream
detectFile: aBlock do: anotherBlock
| file | file := aBlock value. ^ file ifNil: [ nil ] ifNotNil: [ [anotherBlock value: file] ensure: [file close]]
fileNamed: fileName ^ self concreteStream fileNamed: (self fullName: fileName)
fileNamed: fileName do: aBlock "Avi Bryant says, ''This idiom is quite common in other languages that make heavy use of closures (i.e. Lisp (with-file 'foo' (f) ...) and Ruby (File.open('foo'){| f|...})). It's time Squeak had it, too.'' Returns the result of aBlock."
^ self detectFile: [ self fileNamed: fileName ] do: aBlock
I have a question: - would not be better to even wrap the on: into the first block of the ensure: message? What do you mean? Can you give an example?
- do we have to close a file even if its creation failed?
Is there anything in the above examples that raises this question? Usually it is the other way round. You can't close a file (that you don't have) if the creation failed. I was wondering about the name of the methods. Is a idiom smthg create aBlock value: smthg smthg destroy not supposed to be called during: ? Norbert
Hi norbert
I have a question: - would not be better to even wrap the on: into the first block of the ensure: message? What do you mean? Can you give an example?
In VW I was used to write something like that from memory [ f := 'foo.bar' asFilename. f open.... ] ensure: [f close] so the file creation was protected.
- do we have to close a file even if its creation failed?
Is there anything in the above examples that raises this question? Usually it is the other way round. You can't close a file (that you don't have) if the creation failed.
I was wondering about the name of the methods. Is a idiom
smthg create aBlock value: smthg smthg destroy
not supposed to be called during: ?
Yes but apparently in FileStream there are newfileNamed:do:.... I guess that this is a ruby idiom imported by avi Stef
Norbert
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
I tend to protect the asFilename/open inside the block as you describe but I would guess it depends on what resources are allocated as to whether you need the close. I was additionally wondering about the pattern ^file ifNil: [ nil ] ifNotNil: [ ...] if file is nil, then does it not answer self to ifNotNil: ? ^file ifNotNil: [...] thanks Mike On Wed, Jul 16, 2008 at 9:33 AM, Stéphane Ducasse <stephane.ducasse@inria.fr> wrote:
Hi norbert
I have a question: - would not be better to even wrap the on: into the first block of the ensure: message?
What do you mean? Can you give an example?
In VW I was used to write something like that from memory
[ f := 'foo.bar' asFilename. f open....
] ensure: [f close]
so the file creation was protected.
- do we have to close a file even if its creation failed?
Is there anything in the above examples that raises this question? Usually it is the other way round. You can't close a file (that you don't have) if the creation failed.
I was wondering about the name of the methods. Is a idiom
smthg create aBlock value: smthg smthg destroy
not supposed to be called during: ?
Yes but apparently in FileStream there are newfileNamed:do:.... I guess that this is a ruby idiom imported by avi
Stef
Norbert
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Hi norbert
I have a question: - would not be better to even wrap the on: into the first block of the ensure: message? What do you mean? Can you give an example?
In VW I was used to write something like that from memory
[ f := 'foo.bar' asFilename. f open....
] ensure: [f close]
so the file creation was protected.
If a file fails to open for whatever reason the result will be nil, if you protect the open, then you'll end up trying to close nil during the ensure. Nil is the failure message for Squeaks file operations, exceptions are not thrown. fileNamed: aName do: aBlock | file | file := self fileNamed: aName. ^ file ifNil: [ nil ] ifNotNil: [ [ aBlock value: file ] ensure: [ file close ] ] Seems correct to me, you only need the ensure if the file opened successfully in which case file won't be nil. Ramon Leon http://onsmalltalk.com
participants (4)
-
Michael Roberts -
Norbert Hartl -
Ramon Leon -
Stéphane Ducasse