Boost logo

Boost :

From: Beman Dawes (bdawes_at_[hidden])
Date: 2002-03-21 10:46:29


At 05:42 AM 3/21/2002, Ross Smith wrote:

>-- Dividing everything into "is_directory()" vs "is_file()" doesn't work
>on Unix, where there are any number of other things a file system object
>might be (devices, pipes, etc.).

See response in another post.

>-- is_read_only() is nontrivial on Unix, where it would require
>complicated checking on user identity, group membership, etc. If the
>comment "doesn't imply writable; permissions or the like may make a
>non-read-only file still not writable" was intended to cover this, and
>to imply that only one (which one?) of the permission bits is checked,
>then I can't see the point of having the function at all.

Ugh. I wasn't very clear.

How about this:

!is_read_only() doesn't imply writing to the file will succeed. The intent
is, however, that opening a !is_read_only() file for output would succeed
as long as there weren't errors unrelated to read/write status. A usage
example would be opening a file for reading only if read-only (such as on a
CD-ROM), but otherwise opening for both reading or writing.

>-- There are several versions of "remove" covering various combinations
>of file vs directory, remove recursively vs throw if not empty, remove
>if exists vs throw if not, but I can't see one for "remove this object,
>regardless of whether it's a file or directory; if it's a directory,
>remove recursively; if it doesn't exist, silently do nothing" (i.e. the
>equivalent of rm -rf), which strikes me as by far the most common
>desired semantics.

Yes, that functional is missing. It's deliberate because that operation
seems somewhat unsafe to me, and the interface was getting fat.

I'm not sure what the best solution is. I'll think about it some more.

>-- In general, I think you've leaned too far in the "throw on anything
>at all out of the ordinary" direction without providing corrseponding
>"go ahead and do it anyway" options. E.g. copy_file() and rename() offer
>no overwrite option.

One way to lighten up a bit would be for is_ functions to just return false
if !exist() rather than throwing.

A lot of the heavy-duty programming I do involves execution times measured
in hours or days. That causes users to want errors detected at the
earliest possible moment. But we do need choice because a file system
library will also be used a lot for more casual programs.

>-- Incidentally, regardless of the rename() vs move() question (on which
>I have no particular preference), isn't there a slight inconsistency
>there? I think it should be copy() and rename()|move(), or copy_file()
>and rename_file()|move_file(), for consistency.

Yes, it is somewhat inconsistent. I'll look at those again.

>-- I can't figure out exactly what initial_directory() is supposed to
>do. It clearly has something to do with getcwd() and with providing some
>kind of substitute on systems that don't support getcwd() or the
>equivalent directory, but the detailed semantics aren't clear to me from
>the description. (I can't even parse the sentence "Otherwise, if
>possible, compile or link." Typo there?)

Yes, typo. S/B "compile or link error". I'll expand the docs - the
confusion is that there are five possible behaviors, depending on the
operating system. We would prefer the first behavior for all systems, but
have the others as less and less attractive fallbacks.

>-- What's the difference between is_file() and existing_file() (and
>ditto for ..._directory())?

The inconsistency is to favor of usability.

>-- I'm not sure what prune() does. Putting together clues from the
>surrounding material, I'm guessing that it removes the contents of a
>directory but not the directory itself. That seems a very arcane and
>unusual operation to me; is it really common enough to be worthy of a
>function in its own right?

Since a filtered remove (which is what prune does) by definition may leave
some contents in the directory, trying to then remove the directory would
fail (because the directory might not be empty.) It's like saying "del
*.wrk" or "rm *.wrk" - you wouldn't expect the current directory to also be
deleted!

>
>-- "Rationale for not providing name, regex, or predicate filtered
>versions of remove() or remove_all(): The implication of filtering is
>that the starting directory may not be empty on completion of
>operations. Thus trying to remove it makes no sense." I'm sorry, I just
>can't understand what you're driving at here. Why would it be
>undesirable to be able to easily remove only files that match a
>condition? I would have thought it would be not only desirable but very
>common.

Same as above. You do want to be able to remove the files. That's what
prune does. If you want to take the directory out too, use
remove_all. But it makes no sense to first removes some files, then
removes the rest of the files, then delete the directory. You either want
the directory and entire contents removed, or you want some of the contents
removed, but not the directory itself.

>
>-- Related to some of the above, I see a general pattern of providing
>non-recursive and (sometimes) recursive versions of operations, and
>treating the non-recursive case as the normal case and the recursive one
>as a less prominent variation (when it's provided at all). I would have
>thought it would be the other way around -- usually, the recursive case
>is the one I want nearly all the time, and the non-recursive case is the
>weird special case that's hardly ever useful and often not worth
>bothering to provide a single function for.

I'm sorry, but I've seen far too many disasters when recursive operation is
the default. Would you really want "del *.txt" to be recursive?

The "too many versions of functions yet missing the one I want" argument is
more persuasive, however. Using function naming to select all the options
may be too confusing.

Thanks for all the comments!

--Beman


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk