develooper Front page | perl.perl5.porters | Postings from April 2010

Re: RFC: Perl manual pages -- update to follow the perlstyle.pod guidelines

Thread Previous | Thread Next
From:
Tom Christiansen
Date:
April 3, 2010 15:38
Subject:
Re: RFC: Perl manual pages -- update to follow the perlstyle.pod guidelines
Message ID:
7884.1270334304@chthon
In-Reply-To: Message from Aristotle Pagaltzis <pagaltzis@gmx.de>
   of "Sat, 03 Apr 2010 21:56:29 +0200."
   <20100403195629.GA5903@klangraum.plasmasturm.org>


>* Jari Aalto <jari.aalto@cante.net> [2010-04-03 20:20]:
>> About the "my" everywhere int the loops, I'd suggest adding it
>> everywhere, so that the "quick reader" always sees it:
>>
>>     for my $var ...

> I would agree. `foreach` always aliases the iterator to the list
> items, rather than copying. That means when you use a predeclared
> variable, its old value will be shadowed during the loop and restored
> afterwards.

The construct was designed to be safe and autodeclarative.  It's not like
there's any hidden pitfall here, either, providing strict is in effect, I
suppose.  A new variable either statically or dynamically scoped to the
loop is always created, no matter whether there's an explicit declaration.
That makes it safe to use without clobbering the old value.  It was meant
to work this way: it *is* a declaration because of a local/my.

Yes, it's somewhat clearer to write:

    for my $tick (reverse 1 .. 10) { ... }

    for our $Arg (@ARGV) { ... }

And I do admittedly do this in my own code, except perhaps for implicit $_.

However, I truly do not believe cluttering every example with a declaration
for each variable used makes it clearer or better.  An example that
demonstrates, say, the abs($x) function, should be able to be written

    $x >= 0 ? $x : -$x

without any needlessly distracting declarations.  

Eh?

########################

Similarly,

    dbmopen(%HIST,'/usr/lib/news/history',0666);
    while (($key,$val) = each %HIST) {
       print $key, ' = ', unpack('L',$val), "\n";
    }
    dbmclose(%HIST);

is not improved by being written

    dbmopen(my %HIST,'/usr/lib/news/history',0666);
    while (my($key,$val) = each %HIST) {
       print $key, ' = ', unpack('L',$val), "\n";
    }
    dbmclose(%HIST);

Although it is improved by being written this way:

    dbmopen(%HIST, "/usr/lib/news/history", 0666);
    while (($key, $val) = each %HIST) {
       print $key, " = ", unpack("L", $val), "\n";
    }
    dbmclose(%HIST);

or

    dbmopen(%HIST, "/usr/lib/news/history", 0666);
    while (($key, $val) = each %HIST) {
       printf "%s = %d\n",  $key, unpack("L", $val);
    }
    dbmclose(%HIST);

or

    $dbpath = "/usr/lib/news/history";
    dbmopen(%HIST, $dbpath, 0666)
        || die "can't dbmopen $dbpath: $!";
    while (($key, $val) = each %HIST) {
       printf "%s = %s\n", $key, 
           scalar localtime(unpack("L", $val));
    }
    dbmclose(%HIST);

but perhaps not

    use Fcntl qw[ :mode ];

    $perms  = S_IRUSR | S_IWUSR
            | S_IRGRP | S_IWGRP
            | S_IROTH | S_IWOTH ;

    $dbpath = "/usr/lib/news/history";

    dbmopen(%HIST, $dbpath, $perms) || die "can't dbmopen $dbpath: $!";

    while (($key, $val) = each %HIST) {
        printf "%s = %s\n", $key, 
            scalar localtime(unpack("L", $val));
    }

    dbmclose(%HIST)                 || die "can't dbmclose $dbpath: $!";

:)/2

########################

Actually, that last one is now awfully close to meriting the
whole treatment,


    my $dbpath = "/usr/lib/news/history";
    our %HIST;  # news history file

    {
        use Fcntl qw[ :mode ];

        my $perms  = S_IRUSR | S_IWUSR
                   | S_IRGRP | S_IWGRP
                   | S_IROTH | S_IWOTH ;

        dbmopen(%HIST, $dbpath, $perms) 
            || die "can't dbmopen $dbpath: $!";
    } 

    while (my($article, $timestamp) = each %HIST) {
        printf "%s = %s\n", 
                $article, 
                     scalar localtime(unpack(L => $timestamp));
    }

    dbmclose(%HIST)                     
        || die "can't dbmclose $dbpath: $!";

(The "\n\t|| die" is so we don't linewrap in nroff.)

But ug!!  Isn't that overkill for perlfunc?  Come on, really.

########################

Similarly, this:

   format Something =
       Test: @<<<<<<<< @||||| @>>>>>
             $str,     $%,    '$' . int($num)
   .

   $str = "widget";
   $num = $cost/$quantity;
   $~ = 'Something';
   write;

is really not dramatically improved by

   my($str, $num);
   format Something =
       Test: @<<<<<<<< @||||| @>>>>>
             $str,     $%,    '$' . int($num)
   .

   $str = "widget";
   $num = $cost/$quantity;
   local $~ = 'Something';
   write;

although I think I might perhaps prefer

   $str = "widget";
   $num = $cost/$quantity;

   format Something =
       Test: @<<<<<<<< @||||| @>>>>>
             $str,     $%,  q($) . int($num)
   .

   $~ = "Something";
   write;

Hm, notice this example if a pram that needs fixing:

    if (fileno(THIS) == fileno(THAT)) {
        print "THIS and THAT are dups\n";
    }

Whoops!

########################

Maybe I should make another pass through perlfunc; I must
have been looking mostly at the English the last time through,
not at the Perl.  I could have done a better job.  Sorry.

########################

BTW, the reason why examples like this:

   #  0    1    2     3     4    5     6     7     8
   ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
                                               localtime(time);

are *not* written


   # 0     1     2      3      4     5      6      7      8
   ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) =
                                               localtime(time);

is due to the default nroff line length.

I guess you could write it something like this:

   # 0     1     2      3      4      5
   ($sec, $min, $hour, $mday, $mon,  $year,
   # 0     1     2      3      4      5

   # ....               6      7      8
                       $wday, $yday, $isdst) = localtime(time());
   # ....               6      7      8


########################

Here's an example of gratuitous my() confusing matters:

   my @abbr = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec );
   print "$abbr[$mon] $mday";
   # $mon=9, $mday=18 gives "Oct 18"

I might have written that as

   @abbr = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
   print "$abbr[$mon] $mday\n";  # use old $mon, $mday vals
   # $mon=9, $mday=18 gives "Oct 18"


On the other hand, I'm pretty vehemently for having all examples that are
(or include) self-contained functions being completely use-strict clean 
WRT declarations, like:

   sub log10 {
       my $n = shift;
       return log($n) / log(10);
   }

Anyway, it's not always obvious what needs doing.  You have to look
at each one, and always remember the display format.

--tom
-- 
    Clear conceptual splits often hide false dichotomies.
        --Larry Wall in <20050330195322.GB22184@wall.org>

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About