I have several Perl related problems.

The biggest one is that I only use Perl sometimes. I am a W2K admin by day and FreeBSD/OS X (no, really, two separate boxes) user by night. At work on W2K sometimes a simple .bat file is all the problem needs, other times there is some (God awful) GUI way to get things done. My network runs fairly smoothly and I like it like that. I don't always have the time to "figure it out" with Perl. Later I often try to implent a Perl(y) solution which brings us to my second biggest problem:

I can't find anything.

This is huge. This is how I get frustrated and look for a "faster" solution. For instance the other day I wanted to open a directory look at some files and move them based on their age. I figured I'd keep today's and yesterday's files and move the rest every few days with an AT job (like cron only really crappy,) so I needed to figure out how to tell Perl to read and process the files by date.

I figure I have to use File::Copy so I know I have that module but I double check with perldoc File::Copy. Perfect. I go to CPAN and go mucking around for some module to help. I have no idea what I am asking though and through some dumb luck I find File::Backup which is a really cool looking module that deals with logfiles but:
C:\Lou\Code>ppm PPM interactive shell (2.2.0) - type 'help' for available commands. PPM> install file::backup Install package 'file-backup?' (y/N): y Installing package 'file-backup'... Error installing package 'file-backup': Read a PPD for 'file-backup', +but it is not intended for this build of Perl (MSWin32-x86-multi-thre +ad) PPM> exit Quit!
Fine! There's more than one way to do it; right? So I check perldoc, come here, I go to Google, I check The Perl Cookbook (both my online & my physical copy) and Perldocs.com but I cannot find a way to process a file by the date.

Now, look, I know what you're thinking (perhaps muttering to your screen) "What a dimwit!" I'm with you! Perl has done nothing wrong. I'm a bonehead. I've probably DONE this before. I can't seem to ask perldoc the right questions. I'm never sure when to use -q or -f so I end up trying both. I guess the problem is that no matter how many times I perldoc perldoc I can't get it straight.

I am filled with shame

PS - I just ended up manually moving the files.
There's more than one way to do it, but only some of them actually work.

Replies are listed 'Best First'.
Re: I can't find anything
by chromatic (Archbishop) on Nov 06, 2003 at 18:53 UTC

    It can be hard to know where to start. I tend to learn by experimentation and osmosis. I spent most of a year writing tiny little experimental programs and changing them, just to see what happened.

    Sometimes it helps to browse through perlfunc, just to see what built-ins Perl has and perlfaq, just to see the common questions. It also helped me a great deal to read through all of the questions on Perl Monks and their answers (as well as comp.lang.perl.misc, in those days), to get a feel for what kind of answers there were.

    One good trick, if you have time, is to take a question you think you might possibly be able to answer, then write a little code to come up with the answer or test your answer. You don't have to respond, but you can check your work against the answers of people who do respond.

    Those approaches don't always give you answers to specific multipart questions, but they do often give you answers to pieces. If you know how to process files and if you know how to find file dates, all that's left is putting them together. Sometimes that's difficult, but writing a little glue is often easier than doing the whole thing yourself.

      I spent most of a year writing tiny little experimental programs and changing them, just to see what happened.

      Most of a year? I've been doing that for most of 8 or so years now... :-)

      "My two cents aren't worth a dime.";
Re: I can't find anything
by shockme (Chaplain) on Nov 06, 2003 at 19:05 UTC
    I feel your pain. When I first started, I used to keep snippets of code in files with names like "read-all-filenames", "connect-to-mysql", etc. That way, until I became more familiar with the concepts, I could quickly put my hands on examples.

    If you haven't already, see How to RTFM in the Tutorials section. It's a very good read, and the follow-up comments are quite helpful too. I refer to it every so often, because I'm always forgetting something.

    As to processing files by date, see Getting and Setting Timestamps in the Cookbook. (My version is out-dated, but if you look in the index under file access -> timestamps, you should be able to find it. It's page 313 in my edition.)

    ($READTIME, $WRITETIME) = (stat($filename))[8,9];

    Since you apparently are going to have to do without File::Copy, there's no shame in making a system call:

    system("copy $oldFile $newFile") == 0 || die "$?\n";

    Hang in there, and keep pounding away. The more you use it, the more familiar it'll become.

    If things get any worse, I'll have to ask you to stop helping me.

Re: I can't find anything
by jdtoronto (Prior) on Nov 06, 2003 at 19:12 UTC
    I have had the same problem, sometimes that answer has been so obvious when I find it that I feel like a little session of auto-flagellation!

    For Windows nyou can refer to the, now more than a little aged, "Learning Perl on Win32 Systems", Schwartz, Olson & Christiansen, O'Reilly, 1997. You can still buy it, or you can read it online on Safari (see oreilly.com).

    Page 123 - stat function
    ...to get at the remaining information for the file call the stat function, which returns pretty much everything the POSIX system call stat returns. Not all fo the stat fields are meaningful under Perl for Win32...

    ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtime, $ctime, $blksize, $blocks) = stat( . . . );
    There is also the File::stat module, which is part of the Perl Core Modules. You will find its documentation in the ActiveState documentation if you are using that package.


      See there's the problem stat didn't have a lot of meaning to me, BUT now it does. Thank you.
      There's more than one way to do it, but only some of them actually work.
        See there's the problem stat didn't have a lot of meaning to me, BUT now it does. Thank you.

        The root of this problem is that there is only one semi portable OS programming interface, and win32 isn't it. If you only have minor knowledge of POSIX then looking for a stat/fstat call would be the first thing you'd think of doing (or even if you didn't know that then you'd probably know to search for "modification time"). IMO, many perl things (from glob to open()) make more sense from a POSIX POV.

        Alas, I'm not really sure how you can solve that. Maybe a learn POSIX in 5 minutes type book would help.

        James Antill
Re: I can't find anything
by perrin (Chancellor) on Nov 06, 2003 at 20:08 UTC
    This really is the problem that Perl Cookbook was meant to solve. I think most of the info you need is in the Directories chapter.

    When you know what you need to do (e.g. "I want to find all the files in a directory that are a day old"), you can ask for help in places like this. No one will be upset with newbie questions as long as your question is phrased as "where should I look for this in the docs?" rather than "please code this for me."

      Yeah I know, I've been here a while. This place is amazing (as opposed the scary flame-fest comp.lang.perl.misc (or Godzilla/Purl Gurl/Kira & Frank Town)). This more of a rant than a question. I've done a lot of cool stuff with Perl (log reading, a lot of log reading) but I get stumped now and again. I just don't use it often enough. I should just take 20 minutes a day a code something, anything, you know until my abs are rock solid ;)
      There's more than one way to do it, but only some of them actually work.
        And when you get stumped, sometimes all you need to do is mutter into the chatterbox "How do I get the last modify date/time for a file?" and you'll get a clue or two...     (but write down the clues in a notes files like someone suggested - I do)
        If PPM doesn't work, you can try this:

        download the module's distibution from CPAN and unzip it in to a temp directory.

        Copy any .pm files (and any subdirectories with .pm files) to the appropriate location under c:\perl\site\lib. e.g. the File::Backup distribution contains a file called Backup.pm which you can copy to c:\perl\site\lib\File\Backup.pm

        Limitations: If the module depends on other modules, you will have to repeat the process for them. You'll have to build the HTML docs yourself - otherwise just use the docs on the web. Finally, this will only work for pure Perl modules.

        I've had to resort to this many times - Parrot/Perl6 where art thou!
Re: I can't find anything
by demerphq (Chancellor) on Nov 06, 2003 at 19:35 UTC

    Sometimes I think there should be a section at the top of Perlfunc that lists the unixisms that have been turned into keywords. Things like 'unlink' and 'stat' are not in the slightest bit intuitive for a non unix person, and as such shouldnt have been used as perl keywords, but since they were they should be highlighted as being derived from the *nix world. (I took me longer than I want to admit when I first started using perl to figure out how to get it to delete a file. :-)


      First they ignore you, then they laugh at you, then they fight you, then you win.
      -- Gandhi

      Seems to like that already happens, from perlfunc
        • Perl Functions by Category ....
          Functions for filehandles, files, or directories

          -X, chdir, chmod, chown, chroot, fcntl, glob, ioctl, link, lstat, mkdir, open, opendir, readlink, rename, rmdir, stat, symlink, sysopen, umask, unlink, utime

        • Portability
          Perl was born in Unix and can therefore access all common Unix system calls. In non-Unix environments, the functionality of some Unix system calls may not be available, or details of the available functionality may differ slightly. The Perl functions affected by this are:

          -X, binmode, chmod, chown, chroot, crypt, dbmclose, dbmopen, dump, endgrent, endhostent, endnetent, endprotoent, endpwent, endservent, exec, fcntl, flock, fork, getgrent, getgrgid, gethostent, getlogin, getnetbyaddr, getnetbyname, getnetent, getppid, getprgp, getpriority, getprotobynumber, getprotoent, getpwent, getpwnam, getpwuid, getservbyport, getservent, getsockopt, glob, ioctl, kill, link, lstat, msgctl, msgget, msgrcv, msgsnd, open, pipe, readlink, rename, select, semctl, semget, semop, setgrent, sethostent, setnetent, setpgrp, setpriority, setprotoent, setpwent, setservent, setsockopt, shmctl, shmget, shmread, shmwrite, socket, socketpair, stat, symlink, syscall, sysopen, system, times, truncate, umask, unlink, utime, wait, waitpid

          For more information about the portability of these functions, see the perlport manpage and other available platform-specific documentation.

      Now I didn't come from a unix background, in fact I wasn't very knowledgable at all, but I managed to find unlink by looking at perlfunc.
      Unlinking (er, I mean deleting) a file can be harder than it looks. In the perl core tests, 1 while unlink $file is often used (to support filesystems that allow multiple versions of a file). This occasionally causes problems when a close() is left out, since at least one platform has the interesting tactic of working around not being able to delete an open file by having unlink() schedule the file for later deletion but return true (causing the 1 while unlink to endlessly loop).

      If you are downvoting this for other than lack of interest, thanks for sending me a message or reply to let me know why so I can do better (or just stay quiet) next time.

      I don't know how much experience with the Unixoid computing world you have, but if you'd been there, you'd notice there is almost nothing in Perl that wasn't in a lesser tool before. We've all heard that Perl is derived from C, shell, awk and sed; until you've learned those tools to a significant degree you won't recognize just how much truth there is in that statement.

      The number of things "chosen" amounts to very nearly zero.

      As such, unlink and friends couldn't have been called any differently.

      I believe that the documentation of the Unixoid assumptions in Perl called for for the folks on Windows actually needs to document a fair amount of additional concepts besides just which function names where used for Perl builtins.

      (I'm twitching to keep myself from it, but cannot help commenting that the more I absorb Unix, the more Windows feels like the far overgrown quick & dirty hack of an 8080 OS it is. And I'm not even talking about the codebase (which has been done from scratch in NT anyway and would be fixable with an undue amount of effort), I'm talking about concepts. Unix, as a design, makes sense. And it's not even perfect - there's a lot to do better yet.)

      Makeshifts last the longest.

Re: I can't find anything
by BrowserUk (Pope) on Nov 06, 2003 at 22:09 UTC

    I assume your still using AS perl 5.6.1?

    One of the best things about upgrading to AS 5.8.0 is that AS have started seperating out their PPD's by platform. Instead of having one PPD containing the binaries for all platforms. They now segregate them by platform, and seem to be making more modules available as well. They do have File::Backup (several versions) for Win32/5.8.0 available.

    Also, if you know of a module that does what you want but can't find a PPD/PPM for it, then it can be worth taking a look at the cpan version. Browsing the source will tell you if the module is a pure-perl module or not -- search for the text "bootstrap". If you don't find it, then it's (usually?) a pure perl module.

    File::Backup is. In this case, you can just File->Save As "site/lib/file/backup.pm". And then

    perl -mFile::Backup -de1 ... Can't locate LockFile/Simple.pm in @INC (@INC contains: d:/Perl/lib d:/Perl/site/lib .) at d:/Perl/site/lib/File/Backup.pm line 14. ...

    Back to search.cpan.org. Find LockFile::Simple and click the view source link.

    ^F "bootstrap" -- Not found. File->Save As... "site/lib/" -> New directory -> "LockFile" -> "Simple.pm" .

    Try the test above again, and away you go. Of course, that doesn't run any test suites, and it's a pain when you find pure perl modules that have XS depedancies, but it's better than always going without.

    I've never managed to get CPAN or CPANPLUS to work on my machine, nor succeeded in tracing through the myriad levels of seemingly endless re-directions enough to work out why that is. For XS - modules it wouldn't do me any good as I don't have the right compiler for AS, and for pure perl modules, its easier to install through my browser than work out what is wrong. I think I'm in a minority (of one?) for feeling this way, but it works for me.

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail

Re: I can't find anything
by guha (Priest) on Nov 06, 2003 at 19:28 UTC

    I think if you check out perlfunc and the section with the functions that start with a -, specifically -M, you will find something usable.

    As others have noted, you will benefit from playing around with these functions, there are 27 of them, and possibly have some fun meanwhile.


Re: I can't find anything
by tilly (Archbishop) on Nov 07, 2003 at 05:59 UTC
    This kind of question is something that chatter is useful for. After all if you don't use it regularly, there is no way that you would ever think of something like:
    foreach my $file (glob("$dir/*")) { next if -M $file < 2; # Do something with this old file }
    But after you have seen it a few times, you have a much better idea what to look for.

    But if you are going to use chatter, I strongly recommend trying to figure out the smallest thing that you need to know which is helpful. For instance, How do I found out how old a file is in Perl? Otherwise you will get a lot of answers that don't address your real problem. Which is frustrating all around. You don't like it because it isn't useful. Whoever is trying to help doesn't like it because their effort isn't going anywhere...

      I guess this depends upon whether you consider the OP's 'problem' to be that he didn't know how to find the date of a file, or that the module he found that would do what he needed to do, but couldn't install it for reasons that he wasn't able to correct.

      My own take was that as he hadn't yet discovered the filetest operators, this was a wheel that he probably shouldn't try to re-invent (yet).

      Sometimes, an open question gets a better answer than a targeted one specifically because it gathers answers from a variety of perspectives?

      Examine what is said, not who speaks.
      "Efficiency is intelligent laziness." -David Dunham
      "Think for yourself!" - Abigail

Re: I can't find anything
by zentara (Archbishop) on Nov 07, 2003 at 17:17 UTC
    I can't find anything.

    The first thing I always do when I need an answer is go to http://groups.google.com and search. The secret is to know which "keywords" to enter, and if the first try dosn't produce results, try a different set of keywords. For instance for your first question, I would enter "perl move files age", and I got a good script on the first page of results.