ftp.nice.ch/Attic/openStep/developer/resources/MiscKitArchive.mbox.tgz#/MiscKitArchive.mbox/Re__MiscFile_opinion.attach/index.rtf

This is index.rtf in view mode; [Download] [Up]

# Now the problem:
# 
# Should I just follow the standard unix system calls like
# 
# - (struct stat *)stat;
# 
# or break them up into something more meaningful (for non unix
# types anyways) ala
# 
# - (int)fileSize;
# 
# - (int)numberHardLinks;
# 
# - (int)ownersUid;

Why not both?

- (..) stat updates and returns the stat, and - (...) individualAttribute calls -stat and then dereferences the stat structure pointer to return the desired attribute.

Suggested API:

/* Stats the encapsulated file path and returns a pointer to the
   stat structure.  The returned value points to a piece of global
   memory -- it will only be valid until the next call to any -
   (...) stat method in any instance of this class (or subclass)
   [this is just bbum's interpretation of one way to do this -- it
   is not thread safe, but saves having to have a stat structure's
   worth of memory associated with every instance.  It also is not
   thread-safe;  should probably have a class level Lock object
   associated with the global stat struct.  Better yet, have a
   (struct stat *) instance variable that is NULL unless the developer
   tells this class that it should run thread-safe].
 */
- (struct stat *)stat;

/* individual attribute query methods.  These methods use -()stat
   to obtain the most current stat() information.  Two versions of
   each method are provided -- one using the traditional unix stat
   structure name, and one that provides a more developer-friendly
   name.
 */
- (dev_t) st_dev;
- (dev_t) device;

- (uid_t) st_uid;
- (uid_t) userID;

- (off_t) st_size;
- (off_t) size;

- (short) st_nlink;
- (short) hardLinks;

... etc ...

The following were the three example methods included with R.Todd's initial call for discussion.   In the interest of trying to create a predictable and intuitive API throughout the MiscKit, I wanted to throw out some general commentary in regards to the grammatical rules one should follow when writing APIs.

# - (int)fileSize;

Considering that the object being messaged represents a File [actually, an inode], the "file" part of the method is redundant.  - (int) size is a more concise name for the method -- it is also more appropriate;  an inode encapsulating a directory, link, or device (anything not a file) also has a size but it isn't really a fileSize.
 
# - (int)numberHardLinks;

This struck me as being awkward.  As an alternative, how about one of the following...

- (int) hardLinks;
- (int) hardLinkCount;

... the first case is simple and easy to remember.  The second case is an extension to the paradigm of using -(int)count to indicate the count of some particular attribute encapsulated within an object (List, HashTable, etc...).
 
# - (int)ownersUid;

Instead of ownsersUid, which is almost as cryptic as the stat structure's name for the same thing; st_uid, how about simply:

- (int) userID;

Succinct, easy to remember, and easy to capitalize.

---

This API brings up another interesting point;  the unix headers declare a bunch of specialized meta-types that are basically simply integers, shorts, etc... Should those be preserved across the MiscKit's API?

Personally, I would like to see the preservation of the types.  It provides more information to the developer and can help ensure that the developer isn't trying to mix apples and oranges.  If portability is a problem -- that is, if a problem arises due to the lack of a specific meta-type definition, the following can be used to ensure that the type is predictably [though possibly not appropriately] defined:

#ifndef uid_t
typedef uid_t int
#endif /* uid_t */

 # Secondly, the return value... Most of the C functions for files
 # return a zero for success and a -1 for error (so you have to
 # read errno for more information). Should I just stick with this
 # or do something different? I thought about returning 0 for
 # success and the errno if failure.

self/nil is convenient for chained evaluation -- but chained evaluation implies that one is NOT checking the success/failure of each individual step in the chain (which, in general, is not a good coding practice).  As well, self/nil introduces a minor amount of added confusion when compared to the unix 0/-1 paradigm;  upon success, a unix return of 0 corresponds to an obj-c return of self... 0 and self are effectively boolean opposites.  As long as we choose a consistent paradigm and stick with it [and provide a COMPLETE API such that the developer doesn't have to drop back to unix stupidity], it shouldn't be a problem.

For distributed objects, one would think passing (int)egers would be more efficient than passing things of type (id).

b.bum

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.