Newbie "undefined value"

N

Nadine

Hello,

I get a "cannot use undefined value as symbol ref at line 45." I have
used strict and -w. I am using CARP. From the command line, my syntax
checks out as OK. From that same command line, if I pass in parameters,
then I get the "undefined value." I thought "strict" would catch all
undefined variables. I am using Perl 5 and Apache.

I had a short script that printed to the browser. Now I am changing it
to print to a file and using parts of Stein's guestbook script. Here is
the resulting script.

#!/usr/bin/perl -w
use strict;
use warnings;
use CGI qw:)standard Carp qw(fatalsToBrowser)); # import shortcuts
use Fcntl qw:)flock); # imports LOCK_EX, LOCK_SH, LOCK_NB

my(
$DATAFILE,
$fh, # File Handle
$TIMEOUT,
$path_name,
$path,
$description,
$lock_type,
);

# give path and name of data file
$DATAFILE="Eval.dat";

my $cgi = CGI->new();
my $value = $cgi->param( 'keyword' ) || '';

sub write_datafile {
my $fh = filelock($DATAFILE,1);
unless ($fh) {
print strong('Sorry, an error occurred: unable to open file.'),p();
Delete('action');
print a({-href=>self_url},'Try again');
return undef;
}
}

# List field names in order.
foreach my $item ( qw(orgclass relevance majorReq course) ) {
my $value = $cgi->param( $item ) || 0;
print $fh "$value . |\n";
}


# Generate web page saying thank you

print $cgi->header,
$cgi->start_html('Thank You'),
$cgi->h2('Thank You'),
$cgi->p("Thank you for your feedback."),
$cgi->p("Return to ", a({-href=>'http://www-rohan.sdsu.edu/~ssrllab/'},
"SSRL Lab home page")),
$cgi->hr({-width=>"100%"}),
$cgi->end_html;


unlock($fh);
1;


sub filelock {
my $path = shift;
my $for_writing = shift;

my ($lock_type,$path_name,$description);

$lock_type = LOCK_EX;
$path_name = ">>$path";
$description = 'writing';
}

local($main::msg,$main::eek:ldsig);
my $handler = sub { $main::msg='timed out';
$SIG{ALRM}=$main::eek:ldsig; };
($main::eek:ldsig,$SIG{ALRM}) = ($SIG{ALRM},$handler);
alarm($TIMEOUT);

open ($fh,$path_name) or
warn("Couldn't open $path for $description: $!"), return undef;

# now try to lock it
unless (flock ($fh,$lock_type)) {
warn("Couldn't get lock for $description (" . ($main::msg ||
"$!") . ")");
alarm(0);
close $fh;
return undef;
}

alarm(0);
return $fh;


sub unlock {
my $fh = shift;
flock($fh,LOCK_UN);
close $fh;
}
 
J

J. Gleixner

Nadine said:
Hello,

I get a "cannot use undefined value as symbol ref at line 45."

It's because this:
# List field names in order.
foreach my $item ( qw(orgclass relevance majorReq course) ) {
my $value = $cgi->param( $item ) || 0;
print $fh "$value . |\n";
}

runs before this:

[...]
open ($fh,$path_name) or
warn("Couldn't open $path for $description: $!"), return undef;


Meaning $fh is an undefined value, when you try to print to it.

If you group all of your subroutines before or after the "main" part of
your code, it might make seeing this much easer. Also, the first '}' in
your filelock sub is likely not in the right place.

See ya
 
M

Malcolm Dew-Jones

Nadine ([email protected]) wrote:
: Hello,

: I thought "strict" would catch all
: undefined variables. I am using Perl 5 and Apache.

Yes, it catches all undefined * variables *.

You have an undefined * value *.

The variable name has been defined, but you are trying to use the value
before you have given it a value. Often this indicates an error, but the
error cannot (in general) be found until the program is running.
 
T

Tad McClellan

Nadine said:
I get a "cannot use undefined value as symbol ref at line 45."


That is not the message you got, why lie to us like that?

What is the *exact* message text?

(We might need to look it up in perldiag.pod. Have you tried that? )

Was this the actual message:

Can't use an undefined value as symbol reference at...

??


Do you us expect to count to find out where line 45 is?

You should have marked it or something if you wanted to
maximize the number of people that will take the time
to look at it.

Have you seen the Posting Guidelines that are posted here frequently?

From the command line, my syntax
checks out as OK.


Because the error is a run-time error, not a compile-time one.

I thought "strict" would catch all
undefined variables.


What documentation did you read that led you to believe that?

"use strict" has nothing to do with undefined variables
(it has to do with un_declared_ variables).

#!/usr/bin/perl -w
use warnings;


Use one or the other, not both.

(use warnings is "better" than -w).

my(
$DATAFILE,

[snip many lines of code]
# give path and name of data file
$DATAFILE="Eval.dat";


It is good programming practice to limit the scope of variables
as much as is possible, so you should declare them near where
you use them:

my $DATAFILE = 'Eval.dat';

Single quotes are better than double quotes, unless you need one
of the two "extra" things that double quotes gives you.

Spaces around operators make code easier to read.

sub write_datafile {


That is a strange name for a function that does not write to a data file...

my $fh = filelock($DATAFILE,1);
unless ($fh) {
print strong('Sorry, an error occurred: unable to open file.'),p();
Delete('action');
print a({-href=>self_url},'Try again');
return undef;
}
}
[snip]

print $fh "$value . |\n";


Is this your real code?

Do you want to print a dot between $value and the vertical bar?

Did you mean:

print $fh $value . "|\n";
or
print $fh $value, "|\n";
or
print $fh "$value|\n"; # preferred

instead?

unlock($fh);


Uh oh...

sub filelock {
my $path = shift;
my $for_writing = shift;


or: my( $path, $for_writing ) = @_;


sub unlock {
my $fh = shift;
flock($fh,LOCK_UN);


There is a race here, between releasing the lock and closing
the filehandle.

You shouldn't unlock, close() will unlock _and_ close for you.
 
T

Tad McClellan

Malcolm Dew-Jones said:
Nadine ([email protected]) wrote:
: Hello,

: I thought "strict" would catch all
: undefined variables. I am using Perl 5 and Apache.

Yes, it catches all undefined * variables *.


s/defined/declared/

( but it doesn't really catch _all_ undeclared variables either.

eg: $main::secret = 42; # is fine by use strict...
)

You have an undefined * value *.

Right.


The variable name has been defined,

s/defined/declared/


but you are trying to use the value
before you have given it a value. Often this indicates an error, but the
error cannot (in general) be found until the program is running.


Right.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top