Reputation: 119806
I have the following code in in a Perl script I'm writing:
#!/usr/bin/perl
use DBI;
use Getopt::Long;
use Time::HiRes;
use Error qw(:try);
....
my $starttime = Time::HiRes::time;
try {
my $dbh = DBI->connect("dbi:Sybase:$server", $username, $password);
$dbh->do("use $database");
my $query="exec OfflineDatabaseReport";
$row = $dbh->selectrow_hashref($query);
$dbh->disconnect();
} catch Error with {
print "boom";
exit 1;
};
my $endtime = Time::HiRes::time;
my $timetaken = $endtime - $starttime;
The script worked fine until I wrapped the data access portion in the try...catch
block. Now I get the following exception thrown:
Can't use string ("1316135985.90893") as a HASH ref while "strict refs" in use at /usr/lib/perl5/site_perl/5.8.8/Error.pm line 217.
I did try setting:
no strict "refs";
But I still get the same error. Am I being naive in my usage of a try/catch
block here?
Upvotes: 1
Views: 3304
Reputation: 56
This is how the parser sees the code:
try({ ... }, catch(Error, with({ ... }, my $endtime = Time::HiRes::time)));
Meaning, it passes the result of setting $endtime
to Time::HiRes::time
as the 2nd argument of the with BLOCK
sub. Looking at the source of Error.pm
, I see:
sub with (&;$) {
@_
}
Which means with BLOCK,SCALAR
is a valid argument list. All it does is pass the arguments up to catch
, which interprets my $endtime = Time::HiRes::time
as its $clauses
. catch
itself returns $clauses
, which turns the whole statement into:
try({ ... }, my $endtime = Time::HiRes::time);
try
assumes $clauses
is a hashref, as you can see by the call to
$clauses->{'finally'}->()
if(defined($clauses->{'finally'}));
So perl tries to use the value of Time::HiRes::time
as a hashref, which it most certainly cannot, since it's actually a scalar with a value of "1316135985.90893".
So yeah, the semicolon at the end of the catch
block.
Upvotes: 3