http://www.perlmonks.org?node_id=1012425


in reply to Re: mkdir in perldoc
in thread mkdir in perldoc

Perhaps because the names of files and directories are generically known as "filenames" in the unix world.
:D

Not knocking you for this, but it's equivalent to Anonymous Monk's "Because", perhaps funneling into Appeal_to_tradition. But seriously, I understand, "FILENAME" here may be a generic term for any named filesystem entry, whether it's a file, link, directory, device, pipe, etc. But mkdir will only make directories, so let's be clear and specific, when that doesn't compromise generality. "mkdir DIRNAME" will in no way cause anyone to misunderstand what will happen.

On the other hand, if there's some great savings in coding so docs and parsers and grammars don't have to handle special cases between things like chdir, mkdir, open, do, require, rmdir, chroot, link, symlink, and other things that take named filesystem entities, I'm all ears. I'm sure the developers have enough to do besides handle pedantic observations like this.

Whoops! See rmdir:

    rmdir FILENAME

    rmdir

    Deletes the directory specified by FILENAME if that directory is empty. If it succeeds it returns true; otherwise it returns false and sets $! (errno). If FILENAME is omitted, uses $_ .

    To remove a directory tree recursively (rm -rf on Unix) look at the rmtree function of the File::Path module.

And chmod and chown look weird, just specifying a list. For example:

    chmod LIST
when the detail says the first element must be the mode. This is better written as:
    chmod MODE, LIST

-QM
--
Quantum Mechanics: The dreams stuff is made of

Replies are listed 'Best First'.
Re^3: mkdir in perldoc (prototypes)
by tye (Sage) on Jan 09, 2013 at 23:40 UTC

    And chmod and chown look weird, just specifying a list. For example:

    chmod LIST

    when the detail says the first element must be the mode. This is better written as:

    chmod MODE, LIST

    Actually, the terse syntax examples given in the Perl documentation convey subtle meaning to those who are aware of the conventions being used and changing "chmod LIST" to "chmod MODE,LIST" would convey incorrect information to such people. (To become such a person, in part, one just needs to read, understand, and remember the 2nd paragraph of perlfunc.)

    $ say "prototype('CORE::chmod')" @

    I don't mind being told "mkdir FILENAME" because it hints at this possibility:

    $ perl -e'mkdir("$ENV{HOME}/.bashrc") or die $!,$/' File exists

    I started down the road of proposing that one of those conventions might actually be involved in the choice of "FILENAME" over "DIRNAME", because I noticed this:

    $ perldoc perlfunc | grep FILENAME | egrep '^ *[a-z]+ [A-Z]' chroot FILENAME mkdir FILENAME,MASK mkdir FILENAME rmdir FILENAME sysopen FILEHANDLE,FILENAME,MODE sysopen FILEHANDLE,FILENAME,MODE,PERMS $ say 'map prototype("CORE::$_"), qw/ chroot mkdir rmdir sysopen /' _ _;$ _ *$$;$

    But that doesn't make sense for a lot of reasons.

    I also noticed:

    $ perldoc perlfunc | grep DIRNAME $ perldoc perlfunc | grep FILENAME | wc -l 16

    So, how does opendir describe its argument?

    $ perldoc -f opendir | head -1 opendir DIRHANDLE,EXPR

    Now, that needs to say "DIRHANDLE" and not "FILEHANDLE", because you can't use a Perl DIRHANDLE as a Perl FILEHANDLE so that distinction is rather important. There is no such distinction between a FILENAME and a DIRNAME for Perl (nor for Unix, nor for Windows).

    But why is that "EXPR" and not "FILENAME"? Well, it is a common choice:

    $ perldoc perlfunc | egrep '^ {7}readlink [A-Z]' readlink EXPR $ perldoc perlfunc | egrep '^ {7}lstat [A-Z]' lstat EXPR $ perldoc perlfunc | egrep '^ {7}do [A-Z]' do BLOCK do SUBROUTINE(LIST) do EXPR Uses the value of EXPR as a filename and executes the c +ontents

    One could argue that "do EXPR" helps to convey the point that "any (other) expression gets interpretted as a file name" as opposed to possibly implying that Perl does something like looking at the value to see if it looks like a file name.

    [ I was surprised to (re)learn this:

    $ perl -we "do findModule(); sub findModule{'nonesuch.pl'}" Use of "do" to call subroutines is deprecated at -e line 1.

    ]

    And that might explain the choice of "EXPR" for these cases as well:

    $ perldoc perlfunc | egrep '^ {7}truncate [A-Z]' truncate FILEHANDLE,LENGTH truncate EXPR,LENGTH $ perldoc perlfunc | egrep '^ {7}stat [A-Z]' stat FILEHANDLE stat EXPR stat DIRHANDLE

    Though, I think the case of noticing FILEHANDLE and DIRHANDLE exceptions really is about examining the value not about different syntax, so I find the "EXPR" choice less valuable here. But changing "stat EXPR" to "stat FILENAME" draws too much attention to the distinction between "FILE" and "DIR" in:

    stat FILEHANDLE stat FILENAME stat DIRHANDLE

    While I think changing "DBNAME" to "FILENAME" would significantly improve the clarity here:

    $ perldoc perlfunc | egrep '^ {7}dbmopen [A-Z]' dbmopen HASH,DBNAME,MASK

    (Because "DBNAME" isn't a "FILENAME" in most contexts I deal with -- though, perhaps "FILENAME" was avoided since suffixes likely get appended.)

    How about places that don't use "EXPR"?

    $ perldoc perlfunc | egrep '^ {7}link ' link OLDFILE,NEWFILE $ perldoc perlfunc | egrep '^ {7}rename ' rename OLDNAME,NEWNAME

    I find "OLDNAME" a much better choice than "OLDFILE". Similar to the starting complaint, "OLDFILE" could be the name of a directory. But more important, for me, is that "OLDFILE" doesn't as clearly convey that what is given is the name of a file not some handle or other representation. I also wouldn't go more explicit like these:

    link OLDFILENAME,NEWFILENAME rename OLDFILENAME,NEWFILENAME

    because I would worry about implying that these can't be used on directories [which isn't something I worry about implying for mkdir() or rmdir()]. One could argue for:

    link OLDNAME,NEWLINKNAME

    but I'd probably depart even further and go with:

    link DESTNAME,NEWNAME

    (I've long found the argument order for link,3 and ln quite confusing, I must admit.)

    After considering the broader context, I think most of the uses of "FILENAME" really should be changed to "DIRNAME". Not because I find those uses of "FILENAME" confusing or inappropriate, but because they are cases where the distinction doesn't matter and so "DIRNAME" is just slightly clearer. (I find many cases that are a lot more in need of improvement than the one that started this thread.)

    Contrast that with changing "lstat EXPR" to "lstat FILENAME". I don't like "lstat FILENAME" as it sounds like it might be trying to imply that you can't use it on directories or links, but only on plain files. But I also see no reason to use "EXPR" for that case. I think I prefer "lstat PATHNAME".

    So my updates would only be as follows:

    So I'd explicitly leave these unchanged:

    chmod LIST chown LIST do BLOCK do SUBROUTINE(LIST) do EXPR rename OLDNAME,NEWNAME sysopen FILEHANDLE,FILENAME,MODE sysopen FILEHANDLE,FILENAME,MODE,PERMS

    - tye        

      Thank you for an excellent exposition. This is exactly the kind of discussion I was hoping for.

      I agree with almost everything you say (and I'll only be slightly annoying by replying further).

      In several cases, such as stat, I would prefer something more generic than FILENAME. Something that conveys FILESYSTEMENTITY, but that doesn't work. I can't come up with anything better.

      In the other direction, some uses of EXPR seem almost lazy by comparison. Once the concept that an expression can be evaluated into a value or list, the docs don't need to use EXPR much. Where it's clear and simple, I'd go for a more descriptive term, such as your lstat PATHNAME example. I especially like localtime EPOCHSECONDS.

      I still don't like chmod LIST, because the first element is distinctly different from the rest. chmod MODE, LIST seems much clearer and more descriptive. In most cases LIST is about as useful as EXPR, if only slightly better in conveying multiple values are possible.

      (Aside: I wish module synopses were on average clearer, as in many cases I have to read deeper to find out that it was easier than the first read.)

      -QM
      --
      Quantum Mechanics: The dreams stuff is made of

        There are a lot of Perl functions that expect a string. And yet there is only one pair that document this in these usage lines:

        $ perldoc perlfunc | egrep '^ {7}[a-z]+ STR' index STR,SUBSTR,POSITION index STR,SUBSTR rindex STR,SUBSTR,POSITION rindex STR,SUBSTR

        I refrained from proposing that a ton of cases of "EXPR" be changed to "STRING" (no, not to "STR", thank you) because there are a lot of cases where the ARGUMENT part is describing a type of syntax rather than a type of data. And, for example, "chop STRING" might convey that you can only write chop('string literal') not chop($variable) (when the opposite is the case).

        That is also why I didn't label any arguments as things like "INT" or "NUMBER" (and note that nobody else before me did either).

        Now, if we can come up with a name that conveys "an expression that will be interpreted as a string" that is hard to interpret as meaning "just a string literal", then I'd change a bunch more "EXPR" items. That would be similar to how I copied the precedent of "abs VALUE" to a lot of cases where a numeric expression is expected. But I, like you, preferred even better names like "rand MAX", "caller DEPTH", and "cos RADIANS".

        I also never used "VARIABLE" as there are two quite different cases that such might imply. One might be tempted to write "chop VARIABLE" to convey that chop expects to be able to modify what it is given in-place (it needs to be an "lvalue"). But there are a lot of lvalues in Perl that are not just "VARIABLE".

        The other case is when nothing more complex than a simple scalar variable is allowed (such as for "FILEHANDLE" in "print FILEHANDLE LIST"). One such is where I was strongly tempted to use "VARIABLE":

        $ perldoc perlfunc | egrep '^ {7}sort ' sort SUBNAME LIST sort BLOCK LIST sort LIST

        Because the "sort SUBNAME LIST" case actually includes the possibility of using a reference to a subroutine, not just a SUBNAME. I'd almost rather it was more specific like:

        sort BLOCK LIST sort SUBNAME LIST sort $SCALAR LIST sort \&SUBNAME LIST sort LIST

        But that would be a significant departure from the rest of the entries. And I actually don't think that \&SUBNAME is allowed. The documentation strongly implies that sort $compare_by{$type} LIST is not allowed (while the examples very much don't clarify that point). But part of this is due to sort just having some of the worst syntax quirks of any Perl function.

        I think a better route is, for the few complex cases, throw in just the shortest canonical syntax examples much earlier:

        sort SUBNAME LIST sort BLOCK LIST sort LIST In list context, this sorts the LIST and returns the sorted list value. In scalar context, the behaviour of "sort()" is undefined. If SUBNAME and BLOCK are omitted, "sort"s in standard string comparison order. Otherwise, SUBNAME or BLOCK provides a subroutine that returns an integer less than, equal to, or greater than 0, depending on how the elements of the list are to be ordered. (The "<=>" and "cmp" operators are extremely useful in such routines.) SUBNAME should be the bareword name of a subroutine or a simple scalar variable (unsubscripted) containing either a subroutine name or a reference to a subroutine. BLOCK is just an anonymous, in-line subroutine. @names = sort @names; @numbers = sort { $a <=> $b } @numbers; sub hi2lo { $b <=> $a } @numbers = sort hi2lo @numbers; my $comparison = \&hi2lo; @numbers = sort $comparison @numbers; # Syntax error: my %comparisons = get_compare_functions(); @numbers = sort $comparisons{hi2lo} @numbers; # Not allowed ^^^^^^^ Beware when trying to sort the list returned from a function call, as the obvious syntax does not do that: @sorted = sort foo($x,$y); # same as: @sorted = sort foo $x,$y; # or as: my @list = ($x,$y); @sorted = sort foo @list; # Put just $x and $y into @sorted, # using foo() to compare the values. You must instead use something like: @sorted = sort( foo($x,$y) ); @sorted = sort { $a cmp $b } foo $x,$y; @sorted = sort +foo($x,$y); @sorted = sort &foo($x,$y); ...describe more esoteric details... ...don't include more examples until later... (so the examples of just syntax stand out)

        - tye        

        (Aside: I wish module synopses were on average clearer, as in many cases I have to read deeper to find out that it was easier than the first read.)

        I've read the argument that this is a feature, being forced to read a function docs and struggle, instead of being able to glance at it to find what you're looking for