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


in reply to Can I clean this up??

It's a simple case of refactoring. I really dislike duplication, since duplication is just asking for bugs. As a note, it seems you're writing to FIL before you open it.
if ($ct > 0) { open(FIL, ">>$myfil") || die "Write to $myfil failed\n"; print FIL "\n$ct "; print FIL ($ct > 1)? "are not available" : "is down"; print FIL " at this time.\n"; close (FIL); system("mailx -s 'Mail Header' myemail < $myfil"); }
Note that you should probably be using something like Mail::Mailer or Mail::SendMail to do the dirty work of sending mail.

In your original code, if your e-mail address changed, you'd have to do twice the work to update it, and further, there is a chance you might miss one of them.

When handling simple pluralization, like what you have here, the ?: operator comes in handy. If you're not familiar with it, here's how it works:
print "\$foo is "; print $foo? "true" : "false"; print "\n";
Or you can compact this to something like so:
print "\$foo is ",($foo? "true" : "false"),"\n";
More idiomatically:
print "There ",(($num == 1)? "is" : "are")," $num camel", (($num == 1)? "" : "s")," for sale.\n";
Or perhaps something more "Old School":
printf("There %s $num camel%s for sale.\n", ($num == 1)? ("is","") : ("are","s"));

Replies are listed 'Best First'.
Re: Can I clean this up??
by Abigail-II (Bishop) on Jul 24, 2002 at 11:32 UTC
    Note that you should probably be using something like Mail::Mailer or Mail::SendMail to do the dirty work of sending mail.
    I can think of reasons why in some cases you might prefer Mail::Mailer over using mailx, but "the dirty work" isn't one of them. When I use Mail::Mailer, I need three lines of code on overhead. One line for the OO overhead, a second line to actually open a mail, and a third line to close the mail.

    When using mailx, I only need 2 lines: one for the open, a second for the close. There's no "dirty work" here - the dirty work is done by mailx!

    I've never had problems using mailx, something I cannot say from Mail::Mailer (or Mail::Send).

    Abigail

      % which mailx which: no mailx in (/bin:/usr/bin:/usr/bin/X11: ...
      One case: RedHat does not install mailx by default, so you'd have to be careful about how you deploy this script. As for the modules, they may be more "expensive" in terms of lines of code and overhead, but I think you get what you pay for. And don't forget, system() calls aren't exactly free either.

      To some extend, I agree with your point. system() calls in command-line scripts may be acceptable, especially for quick hacks. However, if you're talking in general terms, the modules are far more adaptable, especially in something like a mod_perl environment.

      If you need to send mail, you better be using SMTP. Sure, you can use 'mail', but how can you tell if the system actually checks the mail queue. Is the mail daemon even running? Can you even assume it's going to be Sendmail? If you have your own little kingdom where certain things can be taken for granted, you can code accordingly. In general terms, though, such assumptions are risky.
        RedHat does not install mailx by default
        So, you use mail, or whatever RedHat installs by default. I would only use Mail::Mailer for portability reasons, but that wasn't a reason that was mentioned.
        And don't forget, system() calls aren't exactly free either.

        Your point being? Have you ever looked into the works of Mail::Mailer? For Unix like systems, the _default_ is to use an external mail program like mail or mailx. And guess how that's invoked? By doing a fork & exec, just like you would be doing with:

        open my $fh => "| mailx args" or die;
        which my preferred way of calling mailx.
        If you need to send mail, you better be using SMTP. Sure, you can use 'mail', but how can you tell if the system actually checks the mail queue. Is the mail daemon even running? Can you even assume it's going to be Sendmail? If you have your own little kingdom where certain things can be taken for granted, you can code accordingly. In general terms, though, such assumptions are risky.
        Mail::Mailer isn't going to use smtp by default on a Unix system either. If it finds an executable mail or mailx, it will use that, regardless whether there's a mail daemon running or not.

        As for using SMTP, I think you don't realize what you are saying. That also means you have to queue, do DNS lookups, and retry (typical up to 5 days) if there's a non-permanent failure in the delivery. Most scripts want to be finished long before email gets delivered.

        Abigail

        If you need to send mail, you better be using SMTP. Sure, you can use 'mail', but how can you tell if the system actually checks the mail queue. Is the mail daemon even running? Can you even assume it's going to be Sendmail? If you have your own little kingdom where certain things can be taken for granted, you can code accordingly. In general terms, though, such assumptions are risky.

        Well, yes and no. No, you can't assume that the user is using sendmail, but yes, you should assume that he'll be running some kind of mailserver on the local machine, at least if he know what he is doing. Any other configuration will effectively break all kinds of redundancy and failrecovery built into SMTP.

        A Perl script is non-persistent, like any other MUA (Mail User Agent). In other words, if the MUA can't deliver the mail it must fail, even though it might be possible to recover, according to SMTP rules. Many MUA won't even handle MX records, and will fail if the first mailserver in the MX records won't answer, or even worse, will fail if there are just MX records and no A/CNAME records, which is a rather common situation. This problem could be fixed, although there would be problems with the script blocking until the mail is actually delivered, which may take several minutes. Not a situation you wan't in a CGI script. And it still won't be able to handle queuing.

        In my opinion, it's bad design to have a MUA deliver anywhere else than to a mailserver in the local machine. In worst case deliver to a local mailserver that can act as a relay, for example to handle firewall issues. It's extremely bad karma to deliver directly to remote mailserver from a MUA. It will only cause people to call you at 3AM claiming that mail doesn't work.