For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > January 2006 > use of uninitialized value....









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 use of uninitialized value....
DBSMITH@OhioHealth.com

2006-01-25, 6:57 pm

All,

My problem seems to be within the Net::FTP module. I have intentionally
modified my password so that my error routines can be tested, but once the
login
piece fails it continues on, when I would expect that it should die at the
code in red. The uninitialized value is $OHMONSTER, but the FTP piece is
not exiting.
Any help please?
thanks
derek


#!/usr/bin/perl
use strict;
use warnings;
use Net::FTP;
use MIME::Lite;

my ($ftplog,$fref);
my $OHMONSTER;
my $RENAMED = q/OhioHealth.xml/;
my ($monster_date,$passed_new_date) = 0;

sub new_date {

my ($year,$month,$day) = (localtime)[5,4,3];
sprintf ("%04d%02d%02d", ($year += 1900), $month+1,$day);
}
$passed_new_date = new_date();


sub new_date_append {

return $monster_date = "OhioHealth$passed_new_date";
}
$fref = \&new_date_append();


sub mailme {

my $sub = shift;
my $msg = MIME::Lite->new(
From => 'pshrapprd <root@pshrapprd.ohnet>',
To => 'Derek Smith <dbsmith@ohiohealth.com>',
#To => 'PsoftHR Group <xxxxxx@ohiohealth.com>',
Subject => 'HRIS FTP Inbound to monster.com had
problems an,
Type => 'multipart/related');

$msg->attach(
Type => 'TEXT',
Disposition => 'attachment',
Path => "$ftplog",
Filename => "$ftplog");
$msg->send;
}


sub signal {

if ($? == -1) {
print "failed to execute: $!\n";
mailme($!);
}
elsif ($? & 127) {
printf "child dies with signal %d, %s coredump\n",
($? & 127), ($? & 128) ? 'with core' :
'without;
mailme($!);
}
elsif ( $? >> 8) {
printf "child exited with value %d\n", $? >> 8;
mailme($!);
}
else {
mailme();
}

}



sub ftpme {

my $RENAMED = q/OhioHealth.xml/;
my $OHMONSTER;
my $remotehost="ftp.monster.com";
my $remotedir="outbound";
my $user="xxxxxx";
my $pass="xxxxxxxx";

$ftplog="/psofthr/hr88prd/intf/monster/log/interface_monster.log;

print "step 1 open log\n";
open (FTPLOG, ">>$ftplog") || do {print FTPLOG "\ncould not
ope;
print "step 2 init ftp\n";
my $ftp = Net::FTP->new($remotehost, Debug => 10)
|| do {print FTPLOG "\nCannot connect to $remotehost: $!",
mail;
print "step 3 login\n";
$ftp->login($user, $pass) || do {print FTPLOG "\nLogin
failed!: ;
print "step 4 print login failed then set bin\n";
$ftp->binary();
print "step 5 cd directory\n";
$ftp->cwd($remotedir);
print "step 6 for loop\n";
foreach ($ftp->ls()) {
if (/${$fref}\d+\w+/) {
$OHMONSTER = $_;
last;
}
}

#$ftp->rename("$OHMONSTER", "$RENAMED") or do {print FTPLOG
"\n;
line 99 print "OHMONSTER:\t",$OHMONSTER,"\n","RENAMED\t:",$RENAMED,"\n";
line 100 $ftp->rename("$OHMONSTER","$RENAMED");
#signal($!), select( (select(FTPLOG), $|=1 ) [0] ); };
$ftp->quit;
}


if ( $passed_new_date and $$fref ) {
ftpme();
}
#else {
# mailme();
#
#}

_ERROR_

Net::FTP>>> Net::FTP(2.75)
Net::FTP>>> Exporter(5.566)
Net::FTP>>> Net::Cmd(2.26)
Net::FTP>>> IO::Socket::INET(1.26)
Net::FTP>>> IO::Socket(1.27)
Net::FTP>>> IO::Handle(1.21)
Net::FTP=GLOB(0x203f5560)<<< 220 ftp101 Microsoft FTP Service (Version
5.0).
Net::FTP=GLOB(0x203f5560)>>> user xohealthxftp
Net::FTP=GLOB(0x203f5560)<<< 331 Password required for xohealthxftp.
Net::FTP=GLOB(0x203f5560)>>> PASS ....
Net::FTP=GLOB(0x203f5560)<<< 530 User xohealthxftp cannot log in.
step 1 open log
step 2 init ftp
step 3 login
Net::FTP=GLOB(0x203f5560)>>> TYPE I
Net::FTP=GLOB(0x203f5560)<<< 530 Please login with USER and PASS.
Net::FTP=GLOB(0x203f5560)>>> CWD outbound
Net::FTP=GLOB(0x203f5560)<<< 530 Please login with USER and PASS.
Net::FTP=GLOB(0x203f5560)>>> PORT 192,168,97,144,169,122
Net::FTP=GLOB(0x203f5560)<<< 200 PORT command successful.
Net::FTP=GLOB(0x203f5560)>>> NLST
Net::FTP=GLOB(0x203f5560)<<< 530 Please login with USER and PASS.
Use of uninitialized value in print at interface_monster_IN2 line 99.
Use of uninitialized value in string at interface_monster_IN2 line 100.
Net::FTP=GLOB(0x203f5560)>>> RNFR
Net::FTP=GLOB(0x203f5560)<<< 530 Please login with USER and PASS.
Net::FTP=GLOB(0x203f5560)>>> QUIT
Net::FTP=GLOB(0x203f5560)<<< 221 Leaving Monster.Com
step 4 print login failed then set bin
step 5 cd directory
step 6 for loop
OHMONSTER:
RENAMED :OhioHealth.xml



usenet@DavidFilmer.com

2006-01-25, 6:57 pm

DBSMITH@OhioHealth.com wrote:
> when I would expect that it should die at the code in red.


This is usenet. You don't get formatting or coloring here.

Were you expecting it to die here:

> print "step 2 init ftp\n";
> my $ftp = Net::FTP->new($remotehost, Debug => 10)
> || do {print FTPLOG "\nCannot connect to $remotehost: $!", mail;
> print "step 3 login\n";


That doesn't even parse (you don't close your block curly in the do
statement). It looks like you're missing some code (such as, maybe, a
"die" if you actually expect it to die).

Write a mini-program and cut-and-paste just the part of your big
program that's giving you trouble.

--
http://DavidFilmer.com

Tom Phoenix

2006-01-25, 9:56 pm

On 1/25/06, DBSMITH@ohiohealth.com <DBSMITH@ohiohealth.com> wrote:

> My problem seems to be within the Net::FTP module. I have intentionally
> modified my password so that my error routines can be tested, but once th=

e
> login
> piece fails it continues on, when I would expect that it should die at t=

he
> code in red.


I don't see any code in red.

> The uninitialized value is $OHMONSTER, but the FTP piece is
> not exiting.


> print "step 6 for loop\n";
> foreach ($ftp->ls()) {
> if (/${$fref}\d+\w+/) {
> $OHMONSTER =3D $_;
> last;
> }
> }


If the test in the if statement never returns true, $OHMONSTER will
stay uninitialized. Is that the problem you're having? Check to see
whethere it's defined before you continue, if that matters. Hope this
helps!

--Tom Phoenix
Stonehenge Perl Training
DBSMITH@OhioHealth.com

2006-01-26, 6:57 pm


Tom Phoenix
<tom@stonehenge.c
om> To
Sent by: "DBSMITH@ohiohealth.com"
tom.phoenix@gmail <DBSMITH@ohiohealth.com>
.com cc
beginners@perl.org
Subject
01/25/2006 12:26 Re: use of uninitialized value....
PM














> My problem seems to be within the Net::FTP module. I have intentionally
> modified my password so that my error routines can be tested, but once

the
> login
> piece fails it continues on, when I would expect that it should die at

the
> code in red.


I don't see any code in red.

> The uninitialized value is $OHMONSTER, but the FTP piece is
> not exiting.


> print "step 6 for loop\n";
> foreach ($ftp->ls()) {
> if (/${$fref}\d+\w+/) {
> $OHMONSTER = $_;
> last;
> }
> }


If the test in the if statement never returns true, $OHMONSTER will
stay uninitialized. Is that the problem you're having? Check to see
whethere it's defined before you continue, if that matters. Hope this
helps!

****************************************
******************************
****************************************
******************************

Yes indeed the problme is within the OHMONSTER variable. I determined this
through a print.
I was able to rid of the error and exit with a RC of zero when any part of
the Net::FTP failed by using a
return. Here is what I did:

print "step 1 open log\n";
open (FTPLOG, ">>$ftplog") || do {print FTPLOG "\ncould not
open file: $ftplog $!"};
print "step 2 init ftp\n";
my $ftp = Net::FTP->new($remotehost, Debug => 10)
|| do {print FTPLOG "\nCannot connect to $remotehost: $!",
mailme(); return};
print "step 3 login\n";
$ftp->login($user, $pass) || do {print FTPLOG "\nLogin
failed!: $!", mailme(); return};
print "step 4 print login failed then set bin\n";
$ftp->binary();
print "step 5 cd directory\n";
$ftp->cwd($remotedir) || do {print FTPLOG "\nCWD to folder
outbound failed!: $!", mailme(); return};
print "step 6 for loop\n";
foreach ($ftp->ls()) {
if (/${$fref}\d+\w+/) {
$OHMONSTER = $_;
last;
}
else {
print FTPLOG "\nFTP ls() or match failed...file will
not be renamed\n";
last;



Chas Owens

2006-01-26, 6:57 pm

snip
> my $ftp =3D Net::FTP->new($remotehost, Debug =3D> 10)
> || do {print FTPLOG "\nCannot connect to $remotehost: $!"=

,
> mailme(); return};

snip

This is a bit off topic, but I can't look at code like this without
suggesting the following alternative:

near the top of your program say:

{
my $olddie =3D $SIG{__DIE__};
$SIG{__DIE__} =3D sub {
my $error =3D shift;
$olddie->{$error} if ref $olddie;
mailme($error);
#other error stuff here
};
}

Then for the rest of your program you can say

my $ftp =3D Net::FTP->new($remotehost, Debug =3D> 10) or
die "Cannot connect to $remotehost: $!";

This allows you to have a complicated error procedure that is common
to anywhere you use die(). It also makes your code cleaner. If you
want the same functionality without the program ending you can assign
your error handler to $SIG{__WARN__} and use warn() instead.
DBSMITH@OhioHealth.com

2006-01-26, 6:57 pm


snip
> my $ftp = Net::FTP->new($remotehost, Debug => 10)
> || do {print FTPLOG "\nCannot connect to $remotehost:

$!",
> mailme(); return};

snip

This is a bit off topic, but I can't look at code like this without
suggesting the following alternative:

near the top of your program say:

{
my $olddie = $SIG{__DIE__};
$SIG{__DIE__} = sub {
my $error = shift;
$olddie->{$error} if ref $olddie;
mailme($error);
#other error stuff here
};
}

Then for the rest of your program you can say

my $ftp = Net::FTP->new($remotehost, Debug => 10) or
die "Cannot connect to $remotehost: $!";

This allows you to have a complicated error procedure that is common
to anywhere you use die(). It also makes your code cleaner. If you
want the same functionality without the program ending you can assign
your error handler to $SIG{__WARN__} and use warn() instead.

****************************************
****************************************
*************************************
****************************************
****************************************
*************************************

I appreciate the suggestion, but if there is a problem I want the progam to
email then die. So I would replace

the || do lines in the ftp section
with a routine call to? :

my $olddie = $SIG{__DIE__};
$SIG{__DIE__} = sub {
my $error = shift;
$olddie->{$error} if ref $olddie;
mailme($error);
#other error stuff here
};


Derek B. Smith
OhioHealth IT
UNIX / TSM / EDM Teams
614-566-4145

Chas Owens

2006-01-26, 6:57 pm

On 1/26/06, DBSMITH@ohiohealth.com <DBSMITH@ohiohealth.com> wrote:
snip
> I appreciate the suggestion, but if there is a problem I want the progam =

to
> email then die. So I would replace
>
> the || do lines in the ftp section
> with a routine call to? :
>
> my $olddie =3D $SIG{__DIE__};
> $SIG{__DIE__} =3D sub {
> my $error =3D shift;
> $olddie->{$error} if ref $olddie;
> mailme($error);
> #other error stuff here
> };
>

snip

No, that defines the override of the default behaviour of the die()
command (see perldoc -f die). The "|| do { blah };" turns into "or
die 'message';" You put all of the "blah" code in the override.
DBSMITH@OhioHealth.com

2006-01-26, 6:57 pm

>
> the || do lines in the ftp section
> with a routine call to? :
>
> my $olddie = $SIG{__DIE__};
> $SIG{__DIE__} = sub {
> my $error = shift;
> $olddie->{$error} if ref $olddie;
> mailme($error);
> #other error stuff here
> };
>

snip

No, that defines the override of the default behavior of the die()
command (see perldoc -f die). The "|| do { blah };" turns into "or
die 'message';" You put all of the "blah" code in the override.

****************************************
****************************************
***************************
****************************************
****************************************
***************************

ok I read the perldoc and this seems to be the ideal way, but when any
condition fails, meaning
a connection fails, a login fails or a cwd fails I want to update the log
with the appropriate message for each failed
condition. Using this ONE way your way will not do this for me instead I
will have to write THREE of these blocks once for each failure...
UNLESS I can put an if in this routine like so:

my $olddie = $SIG{__DIE__};
$SIG{__DIE__} =

sub {
my $error = shift;
$olddie->{$error} if ref $olddie;


#other error stuff as below
if ($RC == 0) {
print FTPLOG message about connection
mailme($error);
}
elif {
($RC == 1) {
print FTPLOG message about login
mailme($error);
}
else {
($RC == 2) {
print FTPLOG message about cwd
mailme($error);
};

Here would be the ftp calls

my $ftp = Net::FTP->new($remotehost, Debug => 10) or
die "Cannot connect to $remotehost: $!", my $RC=0;

$ftp->login($user, $passs ) or die "Login failed $!", my $RC=1;

$ftp->cwd ($remotedir) or die "CWD failed $!", my $RC=2

Does this make sense logically?

thanks again,
derek


Derek B. Smith
OhioHealth IT
UNIX / TSM / EDM Teams


JupiterHost.Net

2006-01-26, 6:57 pm



> No, that defines the override of the default behavior of the die()
> command (see perldoc -f die). The "|| do { blah };" turns into "or
> die 'message';" You put all of the "blah" code in the override.
>
> ****************************************
****************************************
***************************
> ****************************************
****************************************
***************************
>
> ok I read the perldoc and this seems to be the ideal way, but when any


Derek, please properly quote your replies when replying inline (google
"replying inline") so its easy to tell who said what, in this case no
one knows what you mean by the two long line of stars, and it appears
lile you said both things, perhaps using explatives in between.

Make it easier for people to understand your posts, like so:

> No that defineds ...
> command (see ...
> die 'message ...


ok I read ...
JupiterHost.Net

2006-01-26, 6:57 pm



DBSMITH@OhioHealth.com wrote:

>
> Tom Phoenix
> <tom@stonehenge.c
> om> To
> Sent by: "DBSMITH@ohiohealth.com"
> tom.phoenix@gmail <DBSMITH@ohiohealth.com>
> .com cc
> beginners@perl.org
> Subject
> 01/25/2006 12:26 Re: use of uninitialized value....
> PM


Derek, I'd like to ask again that you ***PLEASE*** remove that from your
posts, it wastes time and bandwidth
JupiterHost.Net

2006-01-26, 6:57 pm

[color=darkred]
>
> the
>
>
> the
>

Cool, its all blue in my mail client so there must be no problem :)

Without trying to sort out the hair ball of code might I recommend
simplifying you condition?


my $ftp = Net::FTP->new(...) or _my_die('Connection failed: ' .
Net:FTP->message());

$ftp->login($user, $pass) or _my_die('Login failed: ' . $ftp->message());


_my_warn('foo is bar') if $foo eq $bar;

sub _my_croak {
my ($msg) = @_;
# put $msg in a file, db, email, whatever
croak $msg;
}

sub _my_carp {
my ($msg) = @_;
# put $msg in a file, db, email, whatever
carp $msg;
}
Chas Owens

2006-01-26, 6:57 pm

On 1/26/06, DBSMITH@ohiohealth.com <DBSMITH@ohiohealth.com> wrote:
snip
> ok I read the perldoc and this seems to be the ideal way, but when any
> condition fails, meaning
> a connection fails, a login fails or a cwd fails I want to update the log
> with the appropriate message for each failed
> condition. Using this ONE way your way will not do this for me instead I
> will have to write THREE of these blocks once for each failure...
> UNLESS I can put an if in this routine like so:
>
> my $olddie =3D $SIG{__DIE__};
> $SIG{__DIE__} =3D
>
> sub {
> my $error =3D shift;
> $olddie->{$error} if ref $olddie;
>
>
> #other error stuff as below
> if ($RC =3D=3D 0) {
> print FTPLOG message about connection
> mailme($error);
> }
> elif {
> ($RC =3D=3D 1) {
> print FTPLOG message about login
> mailme($error);
> }
> else {
> ($RC =3D=3D 2) {
> print FTPLOG message about cwd
> mailme($error);
> };
>
> Here would be the ftp calls
>
> my $ftp =3D Net::FTP->new($remotehost, Debug =3D> 10) or
> die "Cannot connect to $remotehost: $!", my $RC=3D0;
>
> $ftp->login($user, $passs ) or die "Login failed $!", my $RC=3D1;
>
> $ftp->cwd ($remotedir) or die "CWD failed $!", my $RC=3D2
>
> Does this make sense logically?

snip

I believe you are slightly about what is going on when you
register the error handler. It is my fault for not commenting the
code.

my $old_error_handler =3D $SIG{__DIE__}; #get the error handler
currently assigned to die()

# assign an anonymous function to the error handler for die
# we are using an anonymous function instead of a normal function
# to get around needing a global variable to hold the old error handler
# for more information run a google search for closures and perl
$SIG{__DIE__} =3D sub {
my $error =3D shift; #$error now holds the message passed to die()

#if $old_error_handler is set then call it
$old_error_handler->() if ref $old_error_handler eq 'CODE';

#you should consider using one of the logging modules instead
open FTPLOG, '>>', "/path/to/log";
print FTPLOG $error;
close FTPLOG;

mailme($error);
};

#stuff happend

my $ftp =3D Net::FTP->new($remotehost, Debug =3D> 10) or
die "Cannot connect to $remotehost: $!";
$ftp->login($user, $passs ) or die "Login as $user on $remotehost failed $!=
";
$ftp->cwd ($remotedir) or die "Could not change directory to
$remotedirfailed $!";
Chas Owens

2006-01-26, 6:57 pm

On 1/26/06, JupiterHost.Net <mlists@jupiterhost.net> wrote:
snip
> Without trying to sort out the hair ball of code might I recommend
> simplifying you condition?
>
>
> my $ftp =3D Net::FTP->new(...) or _my_die('Connection failed: ' .
> Net:FTP->message());
>
> $ftp->login($user, $pass) or _my_die('Login failed: ' . $ftp->message())=

;
>
>
> _my_warn('foo is bar') if $foo eq $bar;
>
> sub _my_croak {
> my ($msg) =3D @_;
> # put $msg in a file, db, email, whatever
> croak $msg;
> }
>
> sub _my_carp {
> my ($msg) =3D @_;
> # put $msg in a file, db, email, whatever
> carp $msg;
> }

snip

The problem with defining your own versions of die, warn, croak, and
carp is that only your code uses them. If another module croaks or
dies then your custom error handling is not used. This is why we have
access to $SIG{__DIE__} and $SIG{__WARN__} (croak() and carp()
internally use die() and warn() respectivly if I remember correctly).

A quick search of CPAN turned up the Religion module (which I remember
as being a joke module, but seems to have morphed into something
useful) that makes the process of chaining signal handlers together a
little cleaner (I used a closure in my example).
JupiterHost.Net

2006-01-26, 6:57 pm

> The problem with defining your own versions of die, warn, croak, and
> carp is that only your code uses them. If another module croaks or


Thats why you put it in a module and use it in all your scripts and if
it has not already been done and you can find a proper place for it to
go, out it on CPAN so every can use it.

> dies then your custom error handling is not used. This is why we have
> access to $SIG{__DIE__} and $SIG{__WARN__} (croak() and carp()
> internally use die() and warn() respectivly if I remember correctly).


You are still "defining your own versions of die, warn, croak, and carp"
and "only your code uses" still. Just differently :) but when you look
at it later is it die()ing lile normal or custom or ??? having a good
name for it makes it instantly recognizable and infinatelly easier to
maintain:

For example:

Say you're sorting through a 1200 line script I wrote 9 months ago and
find this:

die "oops I did it again: $!";


Now is it:
a) standard die
b) send the error to email
c) INSERT it into a database
d) write it to a file
e) format it for HTML
f) none of the above
g) ask me, the original author, and hope I remember what sort of crack
I was on that day (IE not gonna happen ;p)

However if it had been

_die_to_email("oops I did it again: $!");

_die_to_sql("oops I did it again: $!");

_die_to_file("oops I did it again: $!");

_die_to_html("oops I did it again: $!");

Now I know *exactly* whats going on and pretty much where to look to see
what its doing.

Or at least, even _die("oops I did it again: $!"); (or in my initial
example _my_die()) tells me its no normal die()

You're right that %SIG is there so we can have our way with it (and is
really handy when dealing with forks and children etc) but it doesn't
mean we should (more ambiguous, more error prone, harder to maintain,
etc etc)


The bottom line is:

- both ways are fine
- using a function name that says what its doing makes it clear and
easy to maintain
- redefining the signal handlers is more ambiguous and problematic but
allows you to change the behavior of built in exception handlers. (maybe
more useful to add to a large existing script so it all of a sudden
handles it how you want with only one change but past that feels more
like a hack to me)
- both ways make the OP's code way easier to read (what was the point
of this thread originally anyway)
Chas Owens

2006-01-26, 6:57 pm

On 1/26/06, JupiterHost.Net <mlists@jupiterhost.net> wrote:
>
> Thats why you put it in a module and use it in all your scripts and if
> it has not already been done and you can find a proper place for it to
> go, out it on CPAN so every can use it.


You misunderstand my statement. Overriding the __DIE__ and __WARN__
handler affects all modules. Even the ones you didn't write (for
example the DBI module). This allows you to have your custom error
handling regardless of what called die, warn, carp, or croak.

>
>
> You are still "defining your own versions of die, warn, croak, and carp"
> and "only your code uses" still. Just differently :) but when you look
> at it later is it die()ing lile normal or custom or ??? having a good
> name for it makes it instantly recognizable and infinatelly easier to
> maintain:


No, it makes it harder to maintain since someone else's code may
simply die() and you will lose the error handling. If you override
the signals you can control what happens when you die regardless of
what someone else does in the code. By the way, there is nothing to
stop you from saying:

$SIG{__DIE__} =3D \&my_custom_die;

I just prefer to use closures because I don't like global variables.

>
> For example:
>
> Say you're sorting through a 1200 line script I wrote 9 months ago and
> find this:
>
> die "oops I did it again: $!";
>
> Now is it:
> a) standard die
> b) send the error to email
> c) INSERT it into a database
> d) write it to a file
> e) format it for HTML
> f) none of the above
> g) ask me, the original author, and hope I remember what sort of crack
> I was on that day (IE not gonna happen ;p)


Well, the answer is simple: it is the __DIE__ handler that was defined
by the script. If no __DIE__ handlers are defined then it is a simple
die(). There is no confusion (unless you are bringing it with you).=20
Imagine the same scenario but with your function there instead. How
are you better off? You can do a search for my_custom_die(), but you
can do the same search for __DIE__. All that has happened is that you
have lost the ability to control what foreign code does when it
croak()s or die()s.

>
> However if it had been
>
> _die_to_email("oops I did it again: $!");
>
> _die_to_sql("oops I did it again: $!");
>
> _die_to_file("oops I did it again: $!");
>
> _die_to_html("oops I did it again: $!");
>
> Now I know *exactly* whats going on and pretty much where to look to see
> what its doing.
>
> Or at least, even _die("oops I did it again: $!"); (or in my initial
> example _my_die()) tells me its no normal die()
>
> You're right that %SIG is there so we can have our way with it (and is
> really handy when dealing with forks and children etc) but it doesn't
> mean we should (more ambiguous, more error prone, harder to maintain,
> etc etc)
>
>
> The bottom line is:
>
> - both ways are fine
> - using a function name that says what its doing makes it clear and
> easy to maintain
> - redefining the signal handlers is more ambiguous and problematic but
> allows you to change the behavior of built in exception handlers. (maybe
> more useful to add to a large existing script so it all of a sudden
> handles it how you want with only one change but past that feels more
> like a hack to me)
> - both ways make the OP's code way easier to read (what was the point
> of this thread originally anyway)


TIMTOWTDI, YMMV, etc.

My coding style tends to run towards large modules being manipulated
by small scripts. Having the rule that the modules should croak() or
die() (depending on whichever makes more sense in the context) and the
driver script should handle what happens works for me. Just to prove
that TIMTOWTDI here is another method that achieves a similar effect
using your custom function.

#!/usr/bin/perl

use ModuleA;

eval {
my $obj =3D ModuleA->new;

#do stuff
};
my_custom_die($@) if $@;

I just don't like cluttering up my code with try/catch blocks unless I
am actually catching the error (ie recovering).
JupiterHost.Net

2006-01-26, 6:57 pm



Chas Owens wrote:
> On 1/26/06, JupiterHost.Net <mlists@jupiterhost.net> wrote:
>
>
>
> You misunderstand my statement. Overriding the __DIE__ and __WARN__
> handler affects all modules. Even the ones you didn't write (for
> example the DBI module). This allows you to have your custom error
> handling regardless of what called die, warn, carp, or croak.


Gotcha,

still if I needed ot do that I'd rather:

$SIG{__DIE__} = \&_die_to_email;

now you've got more readbality (especially if you do it right after use
strict and warnings in your script ;p) and the univerasl die() change

>
>
> No, it makes it harder to maintain since someone else's code may
> simply die() and you will lose the error handling. If you override
> the signals you can control what happens when you die regardless of
> what someone else does in the code. By the way, there is nothing to
> stop you from saying:
>
> $SIG{__DIE__} = \&my_custom_die;



Ah, great minds :)

> I just prefer to use closures because I don't like global variables.
>
>
>
>
> Well, the answer is simple: it is the __DIE__ handler that was defined
> by the script. If no __DIE__ handlers are defined then it is a simple
> die(). There is no confusion (unless you are bringing it with you).


erm, i think I'm done with this thread, getting a little to attitudy for
me :) I already had to deal with the abuser of this address (mlists)
earlier this w, I'm finished :)

> Imagine the same scenario but with your function there instead. How
> are you better off? You can do a search for my_custom_die(), but you
> can do the same search for __DIE__. All that has happened is that you
> have lost the ability to control what foreign code does when it
> croak()s or die()s.


I understand, no worries. The OP code was so hard to read I thought a
nicer readable

thing would help in figuring out what they heck they are trying to do in
the first

place instead of making it even harder to read.

Have a great day everyone.
Chas Owens

2006-01-27, 6:57 pm

On 1/27/06, DBSMITH@ohiohealth.com <DBSMITH@ohiohealth.com> wrote:
snip
> Thanks Jay for the hopefully final wrap up to the uninteded long email
> thread. This was a good thing however b/c
> I learned something new in this wonderful thing called Perl.
> I agree and it make sense to use $SIG{__DIE__} for obvious reasons.
> But in my test code I am getting "Useless use of hash element in void
> context at line 30."
> which is the line that has the $overide->{$error}. But when I comment
> out the mailme call I do not get this warning.
>
> #!/usr/bin/perl
> use strict;
> use warnings;
>
>
> sub mailme {
>
> my $sub =3D shift;


why aren't you using $sub (which I would rename $message or $error) in
the body of the message?

> my $msg =3D MIME::Lite->new(
> From =3D> 'pshrapprd <root@pshrapprd.ohnet>',
> To =3D> 'Derek Smith <dbsmith@ohiohealth.com>',
> Subject =3D> 'HRIS FTP Inbound to monster.com had
> problems and or failed!',
> Type =3D> 'multipart/related');
>
> #$msg->attach(
> #Type =3D> 'TEXT',
> #Disposition =3D> 'attachment',
> #Path =3D> "$ftplog",
> #Filename =3D> "$ftplog");
> $msg->send;
> }
>
>
>
>
> my $overide =3D $SIG{__DIE__}; ## get error handler currently assigned =

to
> die()
> $SIG{__DIE__} =3D sub {
> my $error =3D shift;


$override is a coderef, not a hashref. That is if it is set at all.=20
If no handler has been previously registered with __DIE__ then it will
be blank. That is why there is a ref check. Your problem is that you
are using curly braces {} instead of parentheses ().

> $overide->{$error} if (ref $overide);
> mailme($error);
> };
>
> open (LOG, "+</var/log/derek") or die "Was unable to open file: $!";
> close (LOG);

DBSMITH@OhioHealth.com

2006-01-27, 6:57 pm


Chas Owens
<chas.owens@gmail
.com> To
"DBSMITH@ohiohealth.com"
01/27/2006 11:47 <DBSMITH@ohiohealth.com>
AM cc
beginners perl <beginners@perl.org>
Subject
Re: use of uninitialized value....












> Thanks Jay for the hopefully final wrap up to the uninteded long email
> thread. This was a good thing however b/c
> I learned something new in this wonderful thing called Perl.
> I agree and it make sense to use $SIG{__DIE__} for obvious reasons.
> But in my test code I am getting "Useless use of hash element in void
> context at line 30."
> which is the line that has the $overide->{$error}. But when I comment
> out the mailme call I do not get this warning.
>
> #!/usr/bin/perl
> use strict;
> use warnings;
>
>
> sub mailme {
>
> my $sub = shift;


>why aren't you using $sub (which I would rename $message or $error) in
>the body of the message?


> my $msg = MIME::Lite->new(
> From => 'pshrapprd <root@pshrapprd.ohnet>',
> To => 'Derek Smith <dbsmith@ohiohealth.com>',
> Subject => 'HRIS FTP Inbound to monster.com had
> problems and or failed!',
> Type => 'multipart/related');
>
> #$msg->attach(
> #Type => 'TEXT',
> #Disposition => 'attachment',
> #Path => "$ftplog",
> #Filename => "$ftplog");
> $msg->send;
> }
>
>
>
>
> my $overide = $SIG{__DIE__}; ## get error handler currently assigned to
> die()
> $SIG{__DIE__} = sub {
> my $error = shift;


>$override is a coderef, not a hashref. That is if it is set at all.
>If no handler has been previously registered with __DIE__ then it will
>be blank. That is why there is a ref check. Your problem is that you
>are using curly braces {} instead of parentheses ().


> $overide->{$error} if (ref $overide);
> mailme($error);
> };
>
> open (LOG, "+</var/log/derek") or die "Was unable to open file: $!";
> close (LOG);



BEGIN NEW RESPONSE:

no reason I was just testing so yes I am using $error passed to my mail
routine.
understood override is a code reference which explains ( ) as opposed to {
}
Kudos to Chas as he has helped quir a bit!

thanks again dude!
derek

Sponsored Links







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

Copyright 2009 codecomments.com