Hi,
This is a very good question.
I do not have a good answer, but I am replying here with CC to the squeak-dev list because I would like to get a response to this question.
In my own personal experience, when I want to traverse the files and directories, I am in the habit of just using the traditional unix 'find' utility because it does a very good job of this, and it knows how to handle file system dependencies such as links and symlinks. I can use the results of the 'find' command in Squeak, so that works well for me.
But if I want to traverse a file system tree directly in Squeak, is there a good simple way to do it? Presumably one would want to visit each node in the tree and evaluate a block to do something. In the example below, we would want the block to create an instance of class Card for each file node that is visited.
For folks replying on squeak-dev please keep in mind that the question originates from the beginners list, so we are looking for a clear and simple answer :-)
Thanks, Dave
On 2023-10-24 18:27, ruivianapereira@gmail.com wrote:
I'm not a programmer of any kind or language; I'm an amateur. I have a personal digital library with thousands of documents, which are useless unless I manage to classify them. I thought it would be an easy task with Squeak, since it is a quite simple problem, but I'm lacking some solutions, as a beginner. My general cenario: I made a class, lets call it card, to hold information about each work, each author, their location on disk and the relations between authors and works: Object>>#Card (instance var : name, location, notes, tags ... ) Author Work
Object>>#MyLibrary (instance var : authors <aCollection>, works <aCollection>, myLibraryBase <aPath?>)
Than I initialize #MyLibrary instances with a UIManager directoryChooser to establish from the begining a reference to the directory where all the relevant files are. But, because it is thousands of files, I would need an automatic method to «scan» all the relevant files in the directories and subdirectories. Meaning: the method should make a collection of all the files, recursively in subdirectories, and for each one it should create a card. And that's where I got stuck: how do I scan recursively the subdirectories? Most of the new tools are quite confusing for me, namely classes and tools to deal with files.
Can anyone point me in the wright direction, please? Thanks _______________________________________________ Beginners mailing list -- beginners@lists.squeakfoundation.org To unsubscribe send an email to beginners-leave@lists.squeakfoundation.org
| recurse |
“<—-[ this will make a tree of Objects isomorphic to the directory tree on Disk ]” recurse := [ :directory | XXXDirectoryCard new subDirectories:( directory subDirectories “<—-[ somehow you get the subDirectories ]” collect: recurse ) fileCards:( directory files ”<———[ somehow you get the files ]” collect:[ :file | XXXFileCard new author:( file author );”<—[ somehow you get the author ]” etc:( file etc ) ;”<————[ etc ]” yourself ] ) ] value:( myLibraryBase asDirectory )”<——-[ XXX equals your initials like if your name is John Q Public your initials are JQP this is a simple way to stop Class name clashes if Card is a popular Class name because there can only be one Card Class in the system so if multiple people all have a Card Class defined then only the first one to load will be loaded and when the rest try to load there will be a fatal Error Class already exists ]”
String>>asDirectory ^File directory: self “<——-[ or something ]”
[ :recurse | recurse value:( myLibraryBase asDirectory )value: recurse ]value:[ :directory :recurse | XXXDirectoryCard new subDirectories:( directory subDirectories “<—-[ somehow you get the subDirectories ]” collect: recurse ) fileCards:( directory files ”<———[ somehow you get files ]” collect:[ :file | XXXFileCard new author:( file author );”<—[ somehow you get the author ]” etc:( file etc ) ;”<————[ etc ]” yourself ) ]”<——-[ here is a more functional style if you have func disease ][ like me ][ if your compiler even cares ][ probably it does not ][ who knows who cares not me ]”
On Wed, Oct 25, 2023 at 18:57 lewis@mail.msen.com wrote:
Hi,
This is a very good question.
I do not have a good answer, but I am replying here with CC to the squeak-dev list because I would like to get a response to this question.
In my own personal experience, when I want to traverse the files and directories, I am in the habit of just using the traditional unix 'find' utility because it does a very good job of this, and it knows how to handle file system dependencies such as links and symlinks. I can use the results of the 'find' command in Squeak, so that works well for me.
But if I want to traverse a file system tree directly in Squeak, is there a good simple way to do it? Presumably one would want to visit each node in the tree and evaluate a block to do something. In the example below, we would want the block to create an instance of class Card for each file node that is visited.
For folks replying on squeak-dev please keep in mind that the question originates from the beginners list, so we are looking for a clear and simple answer :-)
Thanks, Dave
On 2023-10-24 18:27, ruivianapereira@gmail.com wrote:
I'm not a programmer of any kind or language; I'm an amateur. I have a personal digital library with thousands of documents, which are useless unless I manage to classify them. I thought it would be an easy task with Squeak, since it is a quite simple problem, but I'm lacking some solutions, as a beginner. My general cenario: I made a class, lets call it card, to hold information about each work, each author, their location on disk and the relations between authors and works: Object>>#Card (instance var : name, location, notes, tags ... ) Author Work
Object>>#MyLibrary (instance var : authors <aCollection>, works <aCollection>, myLibraryBase <aPath?>)
Than I initialize #MyLibrary instances with a UIManager directoryChooser to establish from the begining a reference to the directory where all the relevant files are. But, because it is thousands of files, I would need an automatic method to «scan» all the relevant files in the directories and subdirectories. Meaning: the method should make a collection of all the files, recursively in subdirectories, and for each one it should create a card. And that's where I got stuck: how do I scan recursively the subdirectories? Most of the new tools are quite confusing for me, namely classes and tools to deal with files.
Can anyone point me in the wright direction, please? Thanks _______________________________________________ Beginners mailing list -- beginners@lists.squeakfoundation.org To unsubscribe send an email to beginners-leave@lists.squeakfoundation.org
Replying to include the beginners list
On 2023-10-26 05:31, Kjell Godo wrote:
| recurse |
"<---[ this will make a tree of Objects isomorphic to the directory tree on Disk ]" recurse := [ :directory | XXXDirectoryCard new subDirectories:( directory subDirectories "<---[ somehow you get the subDirectories ]" collect: recurse ) fileCards:( directory files "<------[ somehow you get the files ]" collect:[ :file | XXXFileCard new author:( file author );"<--[ somehow you get the author ]" etc:( file etc ) ;"<--------[ etc ]" yourself ] ) ] value:( myLibraryBase asDirectory )"<-----[ XXX equals your initials like if your name is John Q Public your initials are JQP this is a simple way to stop Class name clashes if Card is a popular Class name because there can only be one Card Class in the system so if multiple people all have a Card Class defined then only the first one to load will be loaded and when the rest try to load there will be a fatal Error Class already exists ]"
String>>asDirectory ^File directory: self "<-----[ or something ]"
[ :recurse | recurse value:( myLibraryBase asDirectory )value: recurse ]value:[ :directory :recurse |
XXXDirectoryCard new subDirectories:( directory subDirectories "<---[ somehow you get the subDirectories ]" collect: recurse ) fileCards:( directory files "<------[ somehow you get files ]" collect:[ :file | XXXFileCard new author:( file author );"<--[ somehow you get the author ]" etc:( file etc ) ;"<--------[ etc ]" yourself ) ]"<-----[ here is a more functional style if you have func disease ][ like me ][ if your compiler even cares ][ probably it does not ][ who knows who cares not me ]"
On Wed, Oct 25, 2023 at 18:57 lewis@mail.msen.com wrote:
Hi,
This is a very good question.
I do not have a good answer, but I am replying here with CC to the squeak-dev list because I would like to get a response to this question.
In my own personal experience, when I want to traverse the files and directories, I am in the habit of just using the traditional unix 'find' utility because it does a very good job of this, and it knows how to handle file system dependencies such as links and symlinks. I can use the results of the 'find' command in Squeak, so that works well for me.
But if I want to traverse a file system tree directly in Squeak, is there a good simple way to do it? Presumably one would want to visit each node in the tree and evaluate a block to do something. In the example below, we would want the block to create an instance of class Card for each file node that is visited.
For folks replying on squeak-dev please keep in mind that the question originates from the beginners list, so we are looking for a clear and simple answer :-)
Thanks, Dave
On 2023-10-24 18:27, ruivianapereira@gmail.com wrote:
I'm not a programmer of any kind or language; I'm an amateur. I have a personal digital library with thousands of documents, which are useless unless I manage to classify them. I thought it would be an easy task with Squeak, since it is a quite simple problem, but I'm lacking some solutions, as a beginner. My general cenario: I made a class, lets call it card, to hold information about each work, each author, their location on disk and the relations between authors and works: Object>>#Card (instance var : name, location, notes, tags ... ) Author Work
Object>>#MyLibrary (instance var : authors <aCollection>, works <aCollection>, myLibraryBase <aPath?>)
Than I initialize #MyLibrary instances with a UIManager directoryChooser to establish from the begining a reference to the directory where all the relevant files are. But, because it is thousands of files, I would need an automatic method to «scan» all the relevant files in the directories and subdirectories. Meaning: the method should make a collection of all the files, recursively in subdirectories, and for each one it should create a card. And that's where I got stuck: how do I scan recursively the subdirectories? Most of the new tools are quite confusing for me, namely classes and tools to deal with files.
Can anyone point me in the wright direction, please? Thanks _______________________________________________ Beginners mailing list -- beginners@lists.squeakfoundation.org To unsubscribe send an email to beginners-leave@lists.squeakfoundation.org
Hello,
Note that the question has also been cross-posted to Stack Overflow: https://stackoverflow.com/questions/77360448/pharo-or-squeak-how-to-get-a-li...
The accepted answer there is for the FileSystem programming interface that is also available for Squeak, but not out of the box, contrary to Pharo. FileSystem has a convenient allChildren message that answers a collection with all the recursive subdirectories and files.
In Squeak, without loading any additional extensions, we only have the FileDirectory programming interface. It has similar messages, but apparently none as straightforward as allChildren.
For example, there is a message called withAllSubdirectoriesCollect:, which evaluates a code block for every directory in the tree, and from the directory you can get all the contained files.
(UIManager default chooseDirectory: 'Select directory of the collection' from: FileDirectory default) "This will result in a FileDirectory object unless you cancel the dialog." withAllSubdirectoriesCollect: [:eachDirectory | "eachDirectory is a FileDirectory object." eachDirectory fileEntries do: "This loops through all the files (not subdirectories) in eachDirectory." [:eachFileEntry | "eachFileEntry is a DirectoryEntry object." Transcript show: eachFileEntry fullName; cr]]
Please look up the FileDirectory and DirectoryEntry classes in Squeak to find out what you can do with them, and ask any further questions that you might have.
Instead of writing the file names to the transcript, you could also put the directory entries into a collection of yours, or first convert them to Cards and add them to your library directly.
There is another message that also includes all the files in the traversal directly, not only directories (so you do not need two nested blocks of code), but it seems a bit awkward to me: it is called directoryTreeDo: and it evaluates a code block for each file and directory. As an argument to this code block, it provides a list of the DirectoryEntries that lead to this file or directory... From the user perspective, that is a rather convoluted way to pass the path to the file or directory, in my opinion. But if you just look at the last entry of the provided list, you should be able to get all that you need for each file.
Here is an example:
(UIManager default chooseDirectory: 'Select directory of the collection' from: FileDirectory default) directoryTreeDo: [:each | Transcript show: each last fullName; cr]
`each last` in the block is the DirectoryEntry for the current file or directory. For example, you can seek out only the files by testing with `each last isFile`
... directoryTreeDo: [:each | each last isFile ifTrue: [Transcript show: each last fullName; cr]]
Kind regards, Jakob
Am Do., 26. Okt. 2023 um 03:57 Uhr schrieb lewis@mail.msen.com:
Hi,
This is a very good question.
I do not have a good answer, but I am replying here with CC to the squeak-dev list because I would like to get a response to this question.
In my own personal experience, when I want to traverse the files and directories, I am in the habit of just using the traditional unix 'find' utility because it does a very good job of this, and it knows how to handle file system dependencies such as links and symlinks. I can use the results of the 'find' command in Squeak, so that works well for me.
But if I want to traverse a file system tree directly in Squeak, is there a good simple way to do it? Presumably one would want to visit each node in the tree and evaluate a block to do something. In the example below, we would want the block to create an instance of class Card for each file node that is visited.
For folks replying on squeak-dev please keep in mind that the question originates from the beginners list, so we are looking for a clear and simple answer :-)
Thanks, Dave
On 2023-10-24 18:27, ruivianapereira@gmail.com wrote:
I'm not a programmer of any kind or language; I'm an amateur. I have a personal digital library with thousands of documents, which are useless unless I manage to classify them. I thought it would be an easy task with Squeak, since it is a quite simple problem, but I'm lacking some solutions, as a beginner. My general cenario: I made a class, lets call it card, to hold information about each work, each author, their location on disk and the relations between authors and works: Object>>#Card (instance var : name, location, notes, tags ... ) Author Work
Object>>#MyLibrary (instance var : authors <aCollection>, works <aCollection>, myLibraryBase <aPath?>)
Than I initialize #MyLibrary instances with a UIManager directoryChooser to establish from the begining a reference to the directory where all the relevant files are. But, because it is thousands of files, I would need an automatic method to «scan» all the relevant files in the directories and subdirectories. Meaning: the method should make a collection of all the files, recursively in subdirectories, and for each one it should create a card. And that's where I got stuck: how do I scan recursively the subdirectories? Most of the new tools are quite confusing for me, namely classes and tools to deal with files.
Can anyone point me in the wright direction, please? Thanks _______________________________________________ Beginners mailing list -- beginners@lists.squeakfoundation.org To unsubscribe send an email to beginners-leave@lists.squeakfoundation.org
I have just added this on Stack Overflow, too.
Am Do., 26. Okt. 2023 um 11:13 Uhr schrieb Jakob Reschke jakres+squeak@gmail.com:
Hello,
Note that the question has also been cross-posted to Stack Overflow: https://stackoverflow.com/questions/77360448/pharo-or-squeak-how-to-get-a-li...
The accepted answer there is for the FileSystem programming interface that is also available for Squeak, but not out of the box, contrary to Pharo. FileSystem has a convenient allChildren message that answers a collection with all the recursive subdirectories and files.
In Squeak, without loading any additional extensions, we only have the FileDirectory programming interface. It has similar messages, but apparently none as straightforward as allChildren.
For example, there is a message called withAllSubdirectoriesCollect:, which evaluates a code block for every directory in the tree, and from the directory you can get all the contained files.
(UIManager default chooseDirectory: 'Select directory of the collection' from: FileDirectory default) "This will result in a
FileDirectory object unless you cancel the dialog." withAllSubdirectoriesCollect: [:eachDirectory | "eachDirectory is a FileDirectory object." eachDirectory fileEntries do: "This loops through all the files (not subdirectories) in eachDirectory." [:eachFileEntry | "eachFileEntry is a DirectoryEntry object." Transcript show: eachFileEntry fullName; cr]]
Please look up the FileDirectory and DirectoryEntry classes in Squeak to find out what you can do with them, and ask any further questions that you might have.
Instead of writing the file names to the transcript, you could also put the directory entries into a collection of yours, or first convert them to Cards and add them to your library directly.
There is another message that also includes all the files in the traversal directly, not only directories (so you do not need two nested blocks of code), but it seems a bit awkward to me: it is called directoryTreeDo: and it evaluates a code block for each file and directory. As an argument to this code block, it provides a list of the DirectoryEntries that lead to this file or directory... From the user perspective, that is a rather convoluted way to pass the path to the file or directory, in my opinion. But if you just look at the last entry of the provided list, you should be able to get all that you need for each file.
Here is an example:
(UIManager default chooseDirectory: 'Select directory of the collection' from: FileDirectory default) directoryTreeDo: [:each | Transcript show: each last fullName; cr]
`each last` in the block is the DirectoryEntry for the current file or directory. For example, you can seek out only the files by testing with `each last isFile`
... directoryTreeDo: [:each | each last isFile ifTrue: [Transcript show: each last fullName; cr]]
Kind regards, Jakob
Am Do., 26. Okt. 2023 um 03:57 Uhr schrieb lewis@mail.msen.com:
Hi,
This is a very good question.
I do not have a good answer, but I am replying here with CC to the squeak-dev list because I would like to get a response to this question.
In my own personal experience, when I want to traverse the files and directories, I am in the habit of just using the traditional unix 'find' utility because it does a very good job of this, and it knows how to handle file system dependencies such as links and symlinks. I can use the results of the 'find' command in Squeak, so that works well for me.
But if I want to traverse a file system tree directly in Squeak, is there a good simple way to do it? Presumably one would want to visit each node in the tree and evaluate a block to do something. In the example below, we would want the block to create an instance of class Card for each file node that is visited.
For folks replying on squeak-dev please keep in mind that the question originates from the beginners list, so we are looking for a clear and simple answer :-)
Thanks, Dave
On 2023-10-24 18:27, ruivianapereira@gmail.com wrote:
I'm not a programmer of any kind or language; I'm an amateur. I have a personal digital library with thousands of documents, which are useless unless I manage to classify them. I thought it would be an easy task with Squeak, since it is a quite simple problem, but I'm lacking some solutions, as a beginner. My general cenario: I made a class, lets call it card, to hold information about each work, each author, their location on disk and the relations between authors and works: Object>>#Card (instance var : name, location, notes, tags ... ) Author Work
Object>>#MyLibrary (instance var : authors <aCollection>, works <aCollection>, myLibraryBase <aPath?>)
Than I initialize #MyLibrary instances with a UIManager directoryChooser to establish from the begining a reference to the directory where all the relevant files are. But, because it is thousands of files, I would need an automatic method to «scan» all the relevant files in the directories and subdirectories. Meaning: the method should make a collection of all the files, recursively in subdirectories, and for each one it should create a card. And that's where I got stuck: how do I scan recursively the subdirectories? Most of the new tools are quite confusing for me, namely classes and tools to deal with files.
Can anyone point me in the wright direction, please? Thanks _______________________________________________ Beginners mailing list -- beginners@lists.squeakfoundation.org To unsubscribe send an email to beginners-leave@lists.squeakfoundation.org
The accepted answer there is for the FileSystem programming interface that is also available for Squeak, but not out of the box, contrary to Pharo. FileSystem has a convenient allChildren message that answers a collection with all the recursive subdirectories and files.
In Squeak, without loading any additional extensions, we only have the FileDirectory programming interface. It has similar messages, but apparently none as straightforward as allChildren.
#allChildren is just one of example of why FileSystem should be avoided. It's a wrong abstraction for accessing a file system at all. An enumerative API should be employed for accessing domains of indefinite size, like a file system. FileSystem is basically unusable on large file systems due to inefficient design.
For example, there is a message called withAllSubdirectoriesCollect:,
which evaluates a code block for every directory in the tree, and from the directory you can get all the contained files.
(UIManager default chooseDirectory: 'Select directory of the collection' from: FileDirectory default) "This will result in a
FileDirectory object unless you cancel the dialog." withAllSubdirectoriesCollect: [:eachDirectory | "eachDirectory is a FileDirectory object." eachDirectory fileEntries do: "This loops through all the files (not subdirectories) in eachDirectory." [:eachFileEntry | "eachFileEntry is a DirectoryEntry object." Transcript show: eachFileEntry fullName; cr]]
^^^ Loop within a loop. Conflicting concerns. #withAllSubdirectoriesCollect: is about collecting up and returning a (potentially huge) list of the valued sub directory's -- but the use case calls for enumerating FileEntry's. You found the method responsible for that, but...
There is another message that also includes all the files in the
traversal directly, not only directories (so you do not need two
nested blocks of code), but it seems a bit awkward to me: it is called directoryTreeDo: and it evaluates a code block for each file and directory. As an argument to this code block, it provides a list of the DirectoryEntries that lead to this file or directory... From the user perspective, that is a rather convoluted way to pass the path to the file or directory, in my opinion. But if you just look at the last entry of the provided list, you should be able to get all that you need for each file.
Here is an example:
(UIManager default chooseDirectory: 'Select directory of the collection' from: FileDirectory default) directoryTreeDo: [:each | Transcript show: each last fullName; cr]
`each last` in the block is the DirectoryEntry for the current file or directory. For example, you can seek out only the files by testing with `each last isFile`
... directoryTreeDo: [:each | each last isFile ifTrue: [Transcript show: each last fullName; cr]]
... you don't like it? Would it be better if directoryTreeDo: were updated to #cull:cull: the current Entry, followed by the path? That way, you could write:
directoryTreeDo: [ : eachEntry | ... ]
if you wanted, or
directoryTreeDo: [ : eachEntry : path | ... ]
if you needed. Something more specific than "awkward" and "convoluted" would help. But the path needs to be accessible, though, to have sufficient use-case coverage.
I myself find Squeak's first-class representations of the file system model and API to be quite nice. It isn't perfect, but much better than its reputation, IMO.
Regards, Chris
Hi Chris,
Am Sa., 28. Okt. 2023 um 23:45 Uhr schrieb Chris Muller asqueaker@gmail.com:
The accepted answer there is for the FileSystem programming interface that is also available for Squeak, but not out of the box, contrary to Pharo. FileSystem has a convenient allChildren message that answers a collection with all the recursive subdirectories and files.
In Squeak, without loading any additional extensions, we only have the FileDirectory programming interface. It has similar messages, but apparently none as straightforward as allChildren.
#allChildren is just one of example of why FileSystem should be avoided. It's a wrong abstraction for accessing a file system at all. An enumerative API should be employed for accessing domains of indefinite size, like a file system. FileSystem is basically unusable on large file systems due to inefficient design.
Agreed that the enumerative API is the better idea *in general*. However the other Stack Overflow answer was already there, so the seemingly simple way had already been anchored. I wished to respond to that, and please mind that the asker stated that they are not a programmer of any kind. Under the circumstances I figured that simple solutions, or simpler-looking solutions, are preferred.
Disagreed that FileSystem were unusable on large file systems. It has two visitor classes for file system traversal, and these are used in allChildren etc. Of course one can use them directly as needed to do it better than eagerly collecting all the entries.
For example, there is a message called withAllSubdirectoriesCollect:, which evaluates a code block for every directory in the tree, and from the directory you can get all the contained files.
(UIManager default chooseDirectory: 'Select directory of the collection' from: FileDirectory default) "This will result in a
FileDirectory object unless you cancel the dialog." withAllSubdirectoriesCollect: [:eachDirectory | "eachDirectory is a FileDirectory object." eachDirectory fileEntries do: "This loops through all the files (not subdirectories) in eachDirectory." [:eachFileEntry | "eachFileEntry is a DirectoryEntry object." Transcript show: eachFileEntry fullName; cr]]
^^^ Loop within a loop. Conflicting concerns. #withAllSubdirectoriesCollect: is about collecting up and returning a (potentially huge) list of the valued sub directory's -- but the use case calls for enumerating FileEntry's. You found the method responsible for that, but...
You are right, I somehow ignored the "collect" in the message name.
But if this is about collecting up a potentially huge list, doesn't it suffer from the same concern as the above-discussed allChildren etc. do?
There is another message that also includes all the files in the
traversal directly, not only directories (so you do not need two nested blocks of code), but it seems a bit awkward to me: it is called directoryTreeDo: and it evaluates a code block for each file and directory. As an argument to this code block, it provides a list of the DirectoryEntries that lead to this file or directory... From the user perspective, that is a rather convoluted way to pass the path to the file or directory, in my opinion. But if you just look at the last entry of the provided list, you should be able to get all that you need for each file.
Here is an example:
(UIManager default chooseDirectory: 'Select directory of the collection' from: FileDirectory default) directoryTreeDo: [:each | Transcript show: each last fullName; cr]
`each last` in the block is the DirectoryEntry for the current file or directory. For example, you can seek out only the files by testing with `each last isFile`
... directoryTreeDo: [:each | each last isFile ifTrue: [Transcript show: each last fullName; cr]]
... you don't like it?
Well, it seems odd to me. It is not what I expected. When I looked at its interface I wondered whether it simply leaked some implementation detail to the user...
Would it be better if directoryTreeDo: were updated to #cull:cull: the current Entry, followed by the path? That way, you could write:
directoryTreeDo: [ : eachEntry | ... ]
if you wanted, or
directoryTreeDo: [ : eachEntry : path | ... ]
if you needed. Something more specific than "awkward" and "convoluted" would help. But the path needs to be accessible, though, to have sufficient use-case coverage.
Yeah, I see; the path may be the problem. The other day I didn't think about FileDirectory not having an abstraction for file paths; so I guess a list of entries is the closest thing that it could provide to get across a relative path. It is a path in the graph sense after all.
What I would have expected is not a list as the block argument, but a single object that allows me to access the current item, be it a file or directory. Since we have only FileDirectory and DirectoryEntry as abstractions, it would thus have to be the last DirectoryEntry. But that is not enough to transport the relative path without computing it again.
In your example, the : path would be the list of entries as we have it today, right? I think your proposal would adequately address my concern. But we cannot change the method like this because it would break backwards compatibility. Also I would not push for it since it was rather a minor cosmetic issue for me.
It isn't perfect, but much better than its reputation, IMO.
It gets the job done, sure. One thing that troubles me about it is that, if you are not familiar with it, it takes a while to find the functionality that you assume must exist because you know it from other systems. I assume that is why the asker posted the original question in the first place. (Although they also didn't find their answer in the FileSystem protocol, so in this case that was not much better.)
For example: almost everyone that I know speaks of "parent" directories. There is no message with "parent" in the protocol of FileDirectory. It is called containingDirectory instead. And taken on its own, that is a fine name, correct and clear. Just not what you might have expected it to be...
Kind regards, Jakob
squeak-dev@lists.squeakfoundation.org