object.enable() anti-pattern

Steven D'Aprano steve+comp.lang.python at pearwood.info
Fri May 10 01:00:53 EDT 2013


On Fri, 10 May 2013 09:36:43 +1000, Cameron Simpson wrote:

> On 09May2013 11:30, Steven D'Aprano
> <steve+comp.lang.python at pearwood.info> wrote: 
> | On Thu, 09 May 2013 18:23:31 +1000, Cameron Simpson wrote: 
> |
> | > On 09May2013 19:54, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
> | > | Steven D'Aprano wrote:
> | > | > There is no sensible use-case for creating a file WITHOUT
> | > | > OPENING it. What would be the point?
> | > |
> | > | Early unix systems often used this as a form of locking. 
> | >
> | > Not just early systems: it's a nice lightweight method of making a
> | > lockfile even today if you expect to work over NFS, where not that
> | > many things are synchronous. You OPEN A FILE with "0" modes 
> | [emphasis added]
>
> | This is all very well and good, but for the life of me, I cannot see
> | how opening a file is a good example of not opening a file. Perhaps it
> | is a Zen thing, like the sound no spoon makes when you don't tap it
> | against a glass that isn't there.
> 
> Because a file usually does not exist in isolation (yes sometimes we
> want an isolated file). Files usually exist in the filesystem, which is
> a namespace. And this is effectively a namespace operation, not a data
> storage operation.
>
> Of course, I can take this the other way: just because I opened it with
> a 0 mode field doesn't mean _I_, the opener, cannot read/write it. I've
> got an open file handle... A race free way to make a scratch file in a
> shared area, for example.


But you are opening the file. Therefore, it cannot possibly be an example 
of not opening the file.

Unlike Pascal, there is no way to create a C file descriptor in a closed 
state. Such a thing does not exist. If you have a file descriptor, the 
file is open. Once you close it, the file descriptor is no longer valid.

But even if C allowed you to do so, doesn't mean that it is a good idea. 
At least some variants of Pascal force you to do the following:

# Pseudo-code.
f = open(filename)
really_open(f)
data = read(f)  # or write, or *any other operation at all*

Surely we can agree that having to call both open() and really_open() 
before you get an actually opened file that you can use is one call too 
many? There is *nothing* you can do with f before calling really_open(). 
So why require it?

(For the record, "really_open" is spelled "reset" or "rewrite" depending 
on whether you want to read or write to the file.)


> The point is probably that a file isn't merely a feature free byte
> storage container; in the real world they usually come with all sorts of
> features like names and permissions. Those features will always imply
> creative uses.

There are at least three related but separate things here.

* file objects, or their low-level equivalent, file descriptors;

* pathnames;

* files on disk, which are an abstraction for data in a particular kind 
of data structure.

They are obviously related, but they are also obviously independent. You 
can have a pathname that doesn't refer to any file on disk; you can have 
a file on disk that has been lost, and therefore is no longer accessible 
via a file name. (If you run fsck or equivalent, the file may be 
recoverable, but the name will be lost.) You can open a file object, then 
unlink it so it no longer points to a file on disk, but does still accept 
read or write calls.

The counter-examples given so far apply to pathnames or files on disk. 
They don't apply to file objects and file descriptors. I have tried 
really hard to be clear that I am talking about file objects. To the 
extent that I have failed, I am sorry.


-- 
Steven



More information about the Python-list mailing list