For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > June 2007 > pr warn die question









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author pr warn die question
Ben Edwards

2007-06-01, 6:59 pm

I have a perl script that uses FTP. If the ftp server can not be
conected to I want to write to a log file and exit with a return code
of 1.

Something like

my $ftp = Net::FTP->new( $remote_host ) or {
print LOGFILE "failed to connect to $remote_host\n"
return(1);
};

But this does not work. So how do I do 2 statements for an or?

Ben

--
Ben Edwards - Bristol, UK
If you have a problem emailing me use
http://www.gurtlush.org.uk/profiles.php?uid=4
(email address this email is sent from may be defunct)
Steve Bertrand

2007-06-01, 6:59 pm

Ben Edwards wrote:
> I have a perl script that uses FTP. If the ftp server can not be
> conected to I want to write to a log file and exit with a return code
> of 1.
>
> Something like
>
> my $ftp = Net::FTP->new( $remote_host ) or {
> print LOGFILE "failed to connect to $remote_host\n"
> return(1);
> };
>
> But this does not work. So how do I do 2 statements for an or?


I did this backwards, it prints on success, but you get the idea. BTW,
the return won't work unless this code is within a subroutine. Even
though it spits an error because of this, you can see that both
statements get processed:

#!/usr/bin/perl -w

use strict;
use Net::FTP;

my $remote_host = 'localhost';

my $ftp = Net::FTP->new ($remote_host);

if ($ftp) {
print "Connected to $remote_host\n";
return(1);
}


....returns this:

%./ftptest.pl
Connected to localhost
Can't return outside a subroutine at ./ftptest.pl line 12.
Chas Owens

2007-06-01, 6:59 pm

On 6/1/07, Ben Edwards <funkytwig@gmail.com> wrote:
snip
> my $ftp = Net::FTP->new( $remote_host ) or {
> print LOGFILE "failed to connect to $remote_host\n"
> return(1);
> };
>
> But this does not work. So how do I do 2 statements for an or?

snip

my $ftp = Net::FTP->new( $remote_host ) or do {
print LOGFILE "failed to connect to $remote_host\n"
return 1;
};
Paul Lalli

2007-06-01, 6:59 pm

On Jun 1, 10:48 am, funkyt...@gmail.com (Ben Edwards) wrote:
> I have a perl script that uses FTP. If the ftp server can not be
> conected to I want to write to a log file and exit with a return code
> of 1.
>
> Something like
>
> my $ftp = Net::FTP->new( $remote_host ) or {
> print LOGFILE "failed to connect to $remote_host\n"
> return(1);
> };
>
> But this does not work. So how do I do 2 statements for an or?


Before I give you the answer, allow me to strongly suggest you abandon
this algorithm, as it leads to bulky confusing code. My preferred way
of seeing this would be:

my $ftp = Net::FTP->new($remote_host);
if (! $ftp ) {
print LOGFILE "failed to connect to $remote_host\n";
return 1;
}

Even more preferred would be to throw an exception, and let the
calling code deal with it:

my $ftp = Net::FTP->new($remote_host) or
die "failed to connect to $remote_host\n";

Then in whatever code calls this command:

eval { connect_to_ftp() };
if ($@) {
print LOGFILE $@;
exit -1;
}


However, to answer your actual question: you need a do{} block.

my $ftp = Net::FTP->new( $remote_host ) or do {
print LOGFILE "failed to connect to $remote_host\n"
return(1);
};

Note that someone else may suggest you do the following:
my $ftp = Net::FTP->new( $remote_host ) or
print LOGFILE "failed to connect to $remote_host\n" and
return(1);

I strongly recommend you do NOT do that. That will only execute the
return() statement if the print() is successful. And especially since
you're printing to a non-STDOUT filehandle, that's not at all a
certainty.

Paul Lalli

Steve Bertrand

2007-06-01, 6:59 pm

You may want to change this line:

> print LOGFILE "failed to connect to $remote_host\n"


to the following:

print LOGFILE "failed to connect to $remote_host: $@\n"

....and it will print the reason why it could not connect as well.

Steve
Chas Owens

2007-06-01, 6:59 pm

On 6/1/07, Paul Lalli <mritty@gmail.com> wrote:
snip
> if (! $ftp ) {

snip

Ugh, use unless () {} rather than if (! ) {}.

snip
> Even more preferred would be to throw an exception, and let the
> calling code deal with it:
>
> my $ftp = Net::FTP->new($remote_host) or
> die "failed to connect to $remote_host\n";
>
> Then in whatever code calls this command:
>
> eval { connect_to_ftp() };
> if ($@) {
> print LOGFILE $@;
> exit -1;
> }

snip

This is the method that should be used in code that is longer than a
page or two or in production quality code. The "or do {}" trick is
just that: a trick. It is useful when you are prototyping or writing
some throwaway code, but it should not be done in production code.
Paul Lalli

2007-06-01, 6:59 pm

On Jun 1, 11:21 am, chas.ow...@gmail.com (Chas Owens) wrote:
> On 6/1/07, Paul Lalli <mri...@gmail.com> wrote:
> snip> if (! $ftp ) {
>
> snip
>
> Ugh, use unless () {} rather than if (! ) {}.


Ugh. Never. The only time unless should ever be used is in postfix
notation, as in:

die "No arguments passed in!" unless @_;

Otherwise, unless is bulky, a waste of space, confusing to new Perl
programmers, and unscalable. (As soon as you add an 'else' clause,
people have to read it two or three times to understand what's being
done). Avoid at all costs.

Paul Lalli

Chas Owens

2007-06-01, 6:59 pm

On 6/1/07, Paul Lalli <mritty@gmail.com> wrote:
> On Jun 1, 11:21 am, chas.ow...@gmail.com (Chas Owens) wrote:
>
> Ugh. Never. The only time unless should ever be used is in postfix
> notation, as in:
>
> die "No arguments passed in!" unless @_;
>
> Otherwise, unless is bulky, a waste of space, confusing to new Perl
> programmers,

snip

Ah, then we have a disagreement. I find the "!" gets lost when
scanning code and if you use "not" instead then you might as well have
used the unless.

snip
> and unscalable. (As soon as you add an 'else' clause,
> people have to read it two or three times to understand what's being
> done). Avoid at all costs.
>
> Paul Lalli

snip

Which is why you never use an unless with an else. If you have

unless ($foo) {
print "false\n";
}

and you find you need an else you change it to an if

if ($foo) {
print "true\n"
} else {
print "false\n";
}
Paul Lalli

2007-06-01, 6:59 pm

On Jun 1, 1:49 pm, chas.ow...@gmail.com (Chas Owens) wrote:
> On 6/1/07, Paul Lalli <mri...@gmail.com> wrote:> On Jun 1, 11:21 am,


>
> Which is why you never use an unless with an else. If you have
>
> unless ($foo) {
> print "false\n";
> }
>
> and you find you need an else you change it to an if
>
> if ($foo) {
> print "true\n"
> } else {
> print "false\n";
> }


Thank you for proving my point for me. :-P

Paul Lalli


Chas Owens

2007-06-01, 6:59 pm

On 6/1/07, Paul Lalli <mritty@gmail.com> wrote:
> On Jun 1, 1:49 pm, chas.ow...@gmail.com (Chas Owens) wrote:
>
>
> Thank you for proving my point for me. :-P
>
> Paul Lalli


Umm, no, I didn't. I agreed with part of what you said. You should
never use an else with an unless, but unless by itself is better, in
my mind, than an if (!) and you can always change it to an if later if
you need to add an else.
Steve Bertrand

2007-06-01, 6:59 pm

Chas Owens wrote:
> On 6/1/07, Paul Lalli <mritty@gmail.com> wrote:
>
> Umm, no, I didn't. I agreed with part of what you said. You should
> never use an else with an unless, but unless by itself is better, in
> my mind, than an if (!) and you can always change it to an if later if
> you need to add an else.


In all honesty, I find removing a ! is easier than changing an if to
unless, especially if just testing something quickly. Also makes it
easier to search for.

Steve
Paul Lalli

2007-06-01, 6:59 pm

On Jun 1, 3:47 pm, chas.ow...@gmail.com (Chas Owens) wrote:
> On 6/1/07, Paul Lalli <mri...@gmail.com> wrote:
>
[color=darkred]
> Umm, no, I didn't. I agreed with part of what you said. You should
> never use an else with an unless, but unless by itself is better, in
> my mind, than an if (!) and you can always change it to an if later if
> you need to add an else.


Exactly. Hence "not scalable". If you have to change existing code
in order to add new code, that's the definition of not scalable. If
you leave it as an if to begin with, you need change nothing to add
the else.

Anyway. This has become a silly argument at this point. I'm content
to let it drop...

Paul Lalli

Dr.Ruud

2007-06-02, 7:58 am

Paul Lalli schreef:

> If you have to change existing code
> in order to add new code, that's the definition of not scalable.


"scalable" is about "doing more of the same", along one or more
axes.

For example: having a webpage full of numbers, that is doing a
separate database query for every number, is not scalable along
the "users" axis.

On the axis of "maintenance effort", there is not much in transforming
an "if(!condition){action}" to an "if(condition){}else{action}". Many
editors can start a macro to do that by a single keystroke.

--
Affijn, Ruud

"Gewoon is een tijger."

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2009 codecomments.com