http://qs321.pair.com?node_id=481238

uksza has asked for the wisdom of the Perl Monks concerning the following question:

Hello Wise Monks,

I just wonder...
If and why should I use i.e. Sys::Syslog or File::Copy instead
my out1 = system("logger bla bla"); my out2 = system("cp 1.txt 2.txt"); my out3 = `/usr/bin/copy 1.txt 2.txt`;
or something like this...

greets
uksza

Replies are listed 'Best First'.
Re: System vs modules
by davorg (Chancellor) on Aug 05, 2005 at 13:31 UTC

    I'd always use a Perl implementation in preference to an external program for two reasons:

    1. Portability: the Perl version will probably work anywhere that Perl works. An external program probably won't.
    2. Efficiency: opening an external program means that your operating system has to start a new process. Doing the all work inside the original process is more efficient.

    There are probably other good reasons, but those two are enough for me.

    --
    <http://dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: System vs modules
by jeteve (Pilgrim) on Aug 05, 2005 at 13:31 UTC
    Hello ! Usually, modules ensure portability.

    In my system, there's no /usr/bin/copy so if your release your code, no chance it will work on my system.

    File::Copy is part of the standard perl itself, so there's no reason not to use it !

    I don't know syslog. I usually use Log::Log4perl . But the idea is the same! Use modules !!

    Hope it helps.
    Nice photos of naked perl sources here !
Re: System vs modules
by Joost (Canon) on Aug 05, 2005 at 13:34 UTC
    Using standard modules should be more portable than external apps.

    File::Copy is portable to every OS perl runs on as far as I know, while cp and copy are not available on every OS. I tend to use File::Copy for all my copying needs.

    On the other hand, I've worked on some solaris installs where Sys::Syslog was not available. YMMV.

    In general, using modules is faster than forking off an external program, especially if you call a lot of them, but some external programs are more efficient than the equivalent perl module, especially when dealing with huge files.

Re: System vs modules
by anonymized user 468275 (Curate) on Aug 05, 2005 at 13:53 UTC
    But, 'never say never!':

    - it might be that the program in question is restricted to interfacing with a non-portable system anyway

    - some modules aren't portable

    - the portability of other solutions within the same system may have been addressed in a way incompatible with the perl module.

    - (etc.)

    Moreover, assuming a module is indeed the best solution for the situation, modular design considerations suggest that you shouldn't plaster it's use all over your application, but rather make your own application as modular as possible by putting your own wrapper module round the usage of the perl module or set of related modules.

    For example, instead of using Data::Dumper in every module and main program under the sun, you might consider having one module called MyDebug.pm that uses Data::Dumper and checks a global variable for whether or not your data debugging requirements are enabled.

    The biggest benefit of this idea is when you find a requirement has to change, you want to be prepared by such techniques to minimise the modifications, instead of potentially searching and editing throughout an entire source tree.

    One world, one people

Re: System vs modules
by mikeraz (Friar) on Aug 05, 2005 at 15:42 UTC

    Why use Perl at all? That, to me, is the essence of your question. If your Perl code is a sequence of system calls you could save yourself some grief with a shell script or batch file.

    Certainly when you're starting in Perl a construct like
         $retval = system "logger -t PERLSEZ TIMTOWTDI Rulz!"
    is a safe and familiar way to get the word out. So (to continue using this example) you can wonder why Tom and Larry bothered to code up Sys::Syslog and what they did to make it worth using. A quick check of the CPAN page shows that you can start by

    use Sys::Syslog; openlog "PERLSEZ", "pid", "LOG_MAIL"; # say it once and let Sys::Syslo +g remember for the duration, save me some typing later # add code as needed
    Now your program will tag each line of your log message with the string PERLSEZ, include the process ID, and send it all to the mail logging system. Later on your program can
    syslog "info", "spammer trying dictionary attack blocking $ipaddr";
    (an action taken thousands of times a day by my system, but that's a different thread)

    Sys::Syslog provides full control over logging. Note that you don't get to specify the facility, which log type, with /usr/bin/logger. Along with the full control your  openlog call will set up some global options so you don't have to specify them on each call. Handy. The other Perl replacements for varied  system "command [args]" have their unique advantages.

    Best of all you get to do both. Use  system ...; until you have a frustration with what it won't do for you then investigate what Perl and CPAN have to offer for alternatives. Play with a few, choose the one that floats your boat and implement it.

    Be Appropriate && Follow Your Curiosity
Re: System vs modules
by Anonymous Monk on Aug 05, 2005 at 14:06 UTC
    I never use File::Copy, as it's not flexible, and just does the wrong thing in certain cases. There are no File::Copy equivalents to cp file1 file2 dir1, or cp -a file1 file2, but what's worse is that File::Copy::copy("file1", "file2") loses the execute bit:
    #!/usr/bin/perl use strict; use warnings; use File::Copy; my ($src, $dest1, $dest2) = ("/tmp/f1", "/tmp/f2", "/tmp/f3"); # Create source file, give it execute permission. open my $fh, "> $src" or die; close $fh or die; chmod 0755, $src or die; die "No execute permission on source\n" unless -x $src; # Make sure destination files are removed. if (-f $dest1) {unlink $dest1 or die;} if (-f $dest2) {unlink $dest2 or die;} # Set umask. umask 022 or die; system "cp $src $dest1" and die; die "Lost execute permission using 'system cp'\n" unless -x $dest1; copy $src, $dest2; die "Lost execute permission using 'File::Copy'\n" unless -x $dest2; __END__ Lost execute permission using 'File::Copy'

    OTOH, I've been using Sys::Syslog for many, many years.

    I tend to use modules if they are good, they are not doing something different than what they are supposed to replace, and if they don't require more typing. I still use my $text = `cat file`; - it does what I need it to do, and it's short.