For example, consider a command like
cp(I'll be talking about the GNU variant here). It has three behaviors:
- You can give it a source file and destination file. It copies it, preserving all attributes if you pass the
- You can give it a source file and a destination directory which already exists. The file is copied into a new file having the same name but inside the destination directory.
- You can give it a list of source files and a destination directory that must already exist. In this case all the files are copied to the destination directory.
Furthermore, if you use the
-rswitch you get recursive directory copying.
All the traditional Unix commands, like
rm, and so on, support a very rich range of behaviors.
My goal was to recreate this using Factor words. As such, I've beefed up Factor's io.files vocabulary considerably. Unlike the shell, where one command can be overloaded to do various things in a "do what I mean" fashion, programming languages should be somewhat more explicit, in my opinion. So what I've done is implemented the equivalent of various Unix commands where each command maps to several words.
First up is deleting files. Factor already had
delete-directoryfor empty directories. What was missing was recursive deletion, so I added
Next up is moving files. Factor had a
rename-fileword but it could also "rename" it to a different directory, so I changed its name to
move-file. I added a
move-file-toword which takes a destination directory:
: move-file-to ( from to -- ) over file-name path+ move-file ;
Also I added a
move-files-toword which takes a sequence of filenames.
For copying, I already had
copy-file. I added
copy-files-to, together with a recursive
I'm still thinking about unifying at least some of these words. For example, instead of
move-files-towe could have a generic
GENERIC# move-to 1 ( from to -- )
M: string move-to over file-name path+ move-file ;
M: sequence move-to [ move-to ] curry each ;
Another thing I'm going to add soon is support for globs when deleting, moving and copying files. To do this I just need to add directory globbing to the glob library, which is pretty trivial.
The glob library could add a third method to the above generic:
M: glob move-to >r file-glob r> move-to ;
Once all of this is done, it should be pretty easy for someone to write a portable file manager using the above features. And don't forget portable directory change notification! Factor's I/O capabilities are looking pretty interesting these days indeed...