[squeak-dev] Re: [ANN] Filesystem 1.0

Colin Putney cputney at wiresong.ca
Sat Nov 21 17:19:43 UTC 2009


On 21-Nov-09, at 12:29 AM, Andreas Raab wrote:

> Thanks. I thought I'd give it a quick try and port the first thing  
> that came into my hands which was FileList. Here is some feedback:

Awesome. Thanks for trying it out. Would you send me that code, so I  
can see the areas that were problematic with a bit more context? I'd  
like to make this simpler.

I rearranged your comments below, so make my responses more  
intelligible.

> Another issue I found bothersome was FSReference vs. FSPath. It is  
> very unclear to me when you use one or the other and given the  
> difficulty to distinguish FSPath from FSReference visually I would  
> strongly vote for making them one and the same to reduce confusion  
> (see FSFilesystem workingDirectory which returns an FSPath vs.  
> FSFilesystem root which returns an FSReference etc).

Yeah, I can see this is an issue. The idea is to use FSReference  
everywhere. Filesystems and paths are meant to be the low-level  
implementation mechanism for references, and you shouldn't have to  
deal with them unless you're doing something exotic. Clearly the  
tutorial is actually confusing more than it's enlightening; I need to  
put references front and centre, and maybe mention paths and  
filesystems in passing.

> From a Windows perspective, the handling of drives and file systems  
> is quite awkward. I would strongly suggest that you drop the idea  
> that drives (or shares) are part of the file system and rather move  
> them into the path representation.

> Etc. The problem is fairly persistent and needlessly so given that  
> treating the drives and shares like virtual directories gives one  
> everything that's needed for dealing nicely with the cross-platform  
> aspects while being able to do the Windows-specific stuff just as  
> well. What I would propose here is that you keep the filesystem  
> distinction (so that someone is able to ask a question like: is this  
> on the same file system?) but move the drive letter / share name  
> into the path.


One fo the advantages of the current arrangement is that all of the  
filesystem-specific code is a subclass of FSFilesystem. If I start  
having FSWindowsPath and FSUnixPath and FSZipPath, it gets harder to  
make things uniform and transparent across different filesystem  
implementations and harder to extend the system with new filesystems.

I realize that this insistence on supporting multiple filesystems with  
a single interface does come with a cost. It makes the simple case of  
files on disk a little more complex. To me, though, being able to use  
the same interface for an alternate filesystem is an important feature.

Take FSMemoryFilesystem, for example. The implementation is pretty  
trivial - it's a toy filesystem, not a real RAM disk. But it's good  
enough for running tests against. Over the years, I've found that the  
single biggest source issues with unit tests is tests that touch the  
filesystem. It slows tests down, causes them to fail even when the  
code is correct, and requires elaborate setUp and tearDown code to  
avoid these problems as much as possible. Running the tests against an  
in-image filesystem makes all that a whole lot easier.

The same is true for ZipArchives. It's valuable to be able to write  
code that doesn't care if the directory structure it's setting up is  
inside a ZipArchive or not. Or on a Ftp server... if FSFtpFilesystem  
ever gets implemented.

I know you probably appreciate all this, but I want to make clear my  
motivation for some of these design choices that may not make sense  
when looking only at the simple files-on-disk case.

>  Just consider for example the root directories that we'd like to  
> display in the file list. Here is how this looks today:

> roots := FileDirectory root directoryNames.
>
> and now with Filesystem:
>  Smalltalk platformName = "Win32"
> 	ifTrue:[^FSWindowsFilesystem disks collect:[:wfs| wfs root]]
>        ifFalse:[^FSDiskFileSystem root entries select:[:d| d  
> isDirectory]].

Yes. I now see that there needs to be a better way to get references  
to the roots of all the available filesystems. (FileDirectory on: '')  
provides this, but there's no way to do the same with Filesystem. It's  
more obvious on Windows systems, but it's a general issue. If the idea  
is to support multiple filesystems, there needs to be a way to find  
out what filesystems are available.

> Otherwise you end up with code like here:
>
>  "Figure out the #localName of the directory to display"
>  localName := aDirectory path basename.
>  "On windows, the local name may be empty and we must look at the
>  embedded filesystem's drive field instead"
>  (Smalltalk platformName = 'Win32' and:[localName isEmpty])
>    ifTrue:[localName := aDirectory filesystem printString].
>
> I mean, eeek. There are several other places where one needs to do  
> stand on one's head to do things mixed with drives and paths on  
> Windows which will make it significantly harder to write cross- 
> platform code.

I suspect this would be easier if you were using references uniformly.  
Assuming aDirectory above is a reference to the root of a filesystem,  
you could just do 'aDirectory printString'. That would get you 'C:\'  
instead of 'C:', but that's not so bad, is it? (The only circumstance  
I can think of for basename to be empty is for a root path. If that's  
happening for another reason, it's a bug.)

> Some smaller issues:
> * FSFileSystem root prints incorrectly 'C:/' instead of 'C:\'

Fixed.

> * FSWindowsFilesystem>>disks should return an ordered array (C:  
> should come before H:)

Fixed.

> * There is no #size on FSReadStream?

Apparently not. :-) I just went through the ANSI spec and implemented  
everything there. There's probably a few more things that should  
obviously be there, but aren't.

> Other than that I got a basic port of FileList working. It's  
> definitely work to port things over, it doesn't come for free. I  
> think there are a few things that could help migration  
> significantly, most importantly implementing #localName and  
> #fullName on FSReference and #modificationTime (in addition to  
> #modificationSeconds) on FSDirectoryEntry because they are so  
> commonly used.


Again, thanks for the detailed feedback. I'll make a new release soon  
that fixes a bunch of this stuff, and then we can argue about the  
design choices more productively.

Colin




More information about the Squeak-dev mailing list