For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > December 2007 > Identify source of warning









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 Identify source of warning
reader@newsguy.com

2007-12-10, 7:01 pm

Can the perl interpreter be made to give more exact warning about
undeclared variables?

I get this warning:

Use of uninitialized value in concatenation (.) \
or string at ../keywa/kywpl line 49.

But there is no code at that line... its a blank line.
The code immediately above has several vars in it but all appear to
have been given some value.

short of perl -d script or checking each possible variable.
Is there a way to make perl do more of the detective work right from
the start?

Yitzle

2007-12-10, 7:01 pm

I guess you are using "use warnings;"
Are you using "use strict;"?
What is the previous line of code? Are you sure the previous line
actually terminates?
Tom Phoenix

2007-12-10, 7:01 pm

On 12/10/07, reader@newsguy.com <reader@newsguy.com> wrote:

> Can the perl interpreter be made to give more exact warning about
> undeclared variables?


Not easily, alas.

> I get this warning:
>
> Use of uninitialized value in concatenation (.) \
> or string at ../keywa/kywpl line 49.
>
> But there is no code at that line... its a blank line.
> The code immediately above has several vars in it but all appear to
> have been given some value.


Appearances are deceiving. Something, probably a variable, on one of
the lines just before line 49 is giving undef instead of a defined
value. (The line number is the one in which perl first realized the
problem, so it should be near, but sometimes after, the true location
of the problem. Modern versions of perl are pretty good about getting
things right for code that's formatted in the usual way, but there
will always be some exceptions.)

> Is there a way to make perl do more of the detective work right from
> the start?


The warning about using undef only happens when you use undef as if it
were a defined value; but by the time the value is being used, perl
has lost track of what variable (or function) supplied the undef in
the first place. Nobody has gone to the trouble, yet, to make a perl
binary that traces undef back to its source. A patch to do so would be
welcomed. Still, all you need to solve your problem is likely to be a
few lines like this just before line 48 or so:

warn "\$foo is undef" unless defined $foo;
warn "\$bar is undef" unless defined $bar;

Some person with an excess of cleverness and time on their hands could
probably whip up a hack using a source filter to do just this. If
they're clever enough not to cause spurious warnings for legitimate
uses of undef, and maybe even if they aren't, it will become a popular
module around these parts. Extra points if they properly handle
functions that return undef.

Hope this helps!

--Tom Phoenix
Stonehenge Perl Training
Paul Johnson

2007-12-10, 7:01 pm

On Mon, Dec 10, 2007 at 10:13:57AM -0800, Tom Phoenix wrote:

> Nobody has gone to the trouble, yet, to make a perl
> binary that traces undef back to its source.


Ah, but they have! Dave Mitchell put this into 5.10, which should be
released in a little over a w.

Our original poster might be interested in compiling up the release
candidate (currently on RC2) and seeing what it says.

--
Paul Johnson - paul@pjcj.net
http://www.pjcj.net
Tom Phoenix

2007-12-10, 7:01 pm

On 12/10/07, Paul Johnson <paul@pjcj.net> wrote:
> On Mon, Dec 10, 2007 at 10:13:57AM -0800, Tom Phoenix wrote:
>
>
> Ah, but they have! Dave Mitchell put this into 5.10, which should be
> released in a little over a w.


How !

--Tom Phoenix
Stonehenge Perl Training
reader@newsguy.com

2007-12-10, 7:01 pm

"Tom Phoenix" <tom@stonehenge.com> writes:

> On 12/10/07, reader@newsguy.com <reader@newsguy.com> wrote:
>
>
> Not easily, alas.
>
>
> Appearances are deceiving. Something, probably a variable, on one of
> the lines just before line 49 is giving undef instead of a defined
> value. (The line number is the one in which perl first realized the
> problem, so it should be near, but sometimes after, the true location
> of the problem. Modern versions of perl are pretty good about getting
> things right for code that's formatted in the usual way, but there
> will always be some exceptions.)


[ First thanks for the info ]

Two claused before line 49 look like:

if ($ARGV[1]){
$OutputFile = pop @ARGV;
if (! -f $OutputFile){
usage();
print "<$OutputFile> cannot be found .. exiting\n";
exit;
}
}

## If no output file was given on cmdline we use a default
if (!$OutputFile){
$OutputFile = "/home/reader/projects/perl/work/myfile";
if(! -f $OutputFile){
usage();
print "<$OutputFile> cannot be found .. exiting\n";
exit;
}
}
[line 49]

Seems like these two by thier nature would not report undef. But I
probably don't know what I think I know about them.

But I did stick an undef in at if (!$OutputFile) so
if (undef $OutputFile)

Then the warning moved on to line 66 where the code attempts to use
OutputFile. Seems to indicate OutputFile was gettiong a varlue in the
if clause.

[...]

> warn "\$foo is undef" unless defined $foo;
> warn "\$bar is undef" unless defined $bar;


Good tip for debugging .. thanks

> Some person with an excess of cleverness...


Well that clearly rules me out. hehe.

Put it looks like Paul has good news on that front. I'm compiling
that version now... Just to see what it does say.

reader@newsguy.com

2007-12-10, 7:01 pm

reader@newsguy.com writes:

> Seems like these two by thier nature would not report undef. But I
> probably don't know what I think I know about them.


Suddenly I cannot recreate the warning. Not sure what happened but
most likely one of those times where I failed to save a change and
then kept thinking I was getting the same error.

At any rate, after making sure it was undef, perl-5.10.0-RC2 does a
nifty job of reporting a similar error further along
(wrapped for mail):

Use of uninitialized value $OutputFile in concatenation (.) or
string at ../keywa/kywpl line 67.

Use of uninitialized value $OutputFile in concatenation (.) or
string at ../keywa/kywpl line 67.


Chas. Owens

2007-12-10, 7:01 pm

On Dec 10, 2007 2:31 PM, <reader@newsguy.com> wrote:
snip
> But I did stick an undef in at if (!$OutputFile) so
> if (undef $OutputFile)
>
> Then the warning moved on to line 66 where the code attempts to use
> OutputFile. Seems to indicate OutputFile was gettiong a varlue in the
> if clause.

snip

That does not do what you think it does. The undef function makes its
argument variable undefined. You are looking for the defined function
like this

if (not defined $OutputFile) {

or this

unless (defined $OutputFile) {

depending on your tastes. Also, there are better ways to write that code:

my $OutputFile = shift || "/home/reader/projects/perl/work/myfile";
die "<$OutputFile> cannot be found .. exiting\n" unless -f $OutputFile;

The shift function defaults to @ARGV when called in the body of
program (it defaults to @_ in subroutines) and the or operator returns
the first true item (if any), so the construct shift || "default" will
return the value from @ARGV if it is set (and non-zero) or the default
value. The die function prints its argument to STDERR (with the file
and line number if it does not end with \n) and exits the program with
a non-zero error code. The new // operator that will be available in
Perl 5.10 returns the first defined item (if any). This makes it a
much better choice for defaulting logic like this.
reader@newsguy.com

2007-12-10, 7:01 pm

"Chas. Owens" <chas.owens@gmail.com> writes:

> On Dec 10, 2007 2:31 PM, <reader@newsguy.com> wrote:
> snip
> snip
>
> That does not do what you think it does. The undef function makes its
> argument variable undefined. You are looking for the defined function
> like this
>
> if (not defined $OutputFile) {
>
> or this
>
> unless (defined $OutputFile) {


Ok, but hold it a minute... I think I must have been unclear in that
post because I wasn't saying I thought using undef there was the way
to go, I did that to try to trip the same warning output. But it
didn't (it caused a similar warning further along as expected) so I
was saying that showed that $OutputFile being undefined was NOT the
reason for the warning this thread was about. (thats probably as clear
as mud too).

> my $OutputFile = shift || "/home/reader/projects/perl/work/myfile";
> die "<$OutputFile> cannot be found .. exiting\n" unless -f $OutputFile;


Now there is something I've been kind of put out about. Maybe because
of being only a sometimes coder or maybe because I arrived at perl
from shell scripting and at one time a sort of heavey (not necessarily
skilled) awk user.

It seems perl coders like to jumble lots of actions into one line.
And think of that as a better way.

I don't doubt it is... and certainly not advocating against advice
from a skilled and experienced user, but can you tell me how it is
better? Is it faster for the interpreter to read or something else?

To me its much harder to read later... mnths later when the script
does something unexpected.. when used in a different way I hadn't
tested it in.

to me:
my $var;
if ($ARGV[0]){
$var = shift;
}
if (!$var){
$var = "someDefaultfile";
}

It is a good bit more drawn out but it tells me more about intent at a
glance than what you used.

If my kind of extra baloney is slowing down the excecution when
taken as a whole .... that is many times more baloney when seen over
300 lines or so than the shorter ways like you posted, then its
probably time for me to give up the long hand and start trying to go
the shorter more concise route.

Can you expound on that a bit?

> The shift function defaults .....


[...] thanks for that nifty info

> ............ The new // operator that will be available in
> Perl 5.10 returns the first defined item (if any). This makes it a
> much better choice for defaulting logic like this.


I just compiled that new version. Paul J. mentioned it has code to
give better warnings and it really does. It actually gives the subject
variable by name in cases like the subject of this thread.

Can you show an example of how that new `//' operator works? I've got
that version built and installed in a test area and all set to be
shocked and amazed at new features... : )

Since all of what I do is either home use or on a webpage of mine. and
won't really cause anyone else (except maybe this list,,) a problem I
think I'll turn the new version loose on my scripts and see what turns
up. Over the yrs I've accumlated over 100 homeboy perl scripts (most
probably very poorly written and some haven't seen that much use).

It will be interesting to see if they all still work.

Paul Johnson

2007-12-10, 7:01 pm

On Mon, Dec 10, 2007 at 04:54:49PM -0600, reader@newsguy.com wrote:

> If my kind of extra baloney is slowing down the excecution when
> taken as a whole .... that is many times more baloney when seen over
> 300 lines or so than the shorter ways like you posted, then its
> probably time for me to give up the long hand and start trying to go
> the shorter more concise route.


I'd stick with what you are happy to maintain.

Personally, I prefer conciseness since I can see more of what I'm trying
to say in less space, and that just helps me when thinking about it.
But being able to understand your code when you come back to it a few
months later trumps that.

> Can you show an example of how that new `//' operator works? I've got
> that version built and installed in a test area and all set to be
> shocked and amazed at new features... : )


my $x = 0;
my $y;

$x || warn "x is false";
$x // warn "x is undefined";

$y || warn "y is false";
$y // warn "y is undefined";

It will probably be used primarily for setting default values where the
value passed in could legitimately be 0 or "".

> Since all of what I do is either home use or on a webpage of mine. and
> won't really cause anyone else (except maybe this list,,) a problem I
> think I'll turn the new version loose on my scripts and see what turns
> up. Over the yrs I've accumlated over 100 homeboy perl scripts (most
> probably very poorly written and some haven't seen that much use).


This would be absolutely wonderful test material for the new release!

> It will be interesting to see if they all still work.


It certainly would. And if you find any which don't, and the reason
can't be tracked back to a problem in your code (or perhaps even if it
can), please use the perlbug utility to report the problem.

Thanks,

--
Paul Johnson - paul@pjcj.net
http://www.pjcj.net
Chas. Owens

2007-12-10, 10:03 pm

On Dec 10, 2007 5:54 PM, <reader@newsguy.com> wrote:
snip
> Ok, but hold it a minute... I think I must have been unclear in that
> post because I wasn't saying I thought using undef there was the way
> to go, I did that to try to trip the same warning output. But it
> didn't (it caused a similar warning further along as expected) so I
> was saying that showed that $OutputFile being undefined was NOT the
> reason for the warning this thread was about. (thats probably as clear
> as mud too).

snip

Undefined values are allowed in logical tests, so using an undef in
them will not trip any warnings. You will get an undef warning when
you try to use an undefined value where a defined one is expected.
For instance:

my $foo;
my $bar = 5 + $foo; #this will trip a warning
my $baz = "the variable \$foo has the value $foo\n"; #this will trip a warning

snip
>
>
> Now there is something I've been kind of put out about. Maybe because
> of being only a sometimes coder or maybe because I arrived at perl
> from shell scripting and at one time a sort of heavey (not necessarily
> skilled) awk user.
>
> It seems perl coders like to jumble lots of actions into one line.
> And think of that as a better way.
>
> I don't doubt it is... and certainly not advocating against advice
> from a skilled and experienced user, but can you tell me how it is
> better? Is it faster for the interpreter to read or something else?
>
> To me its much harder to read later... mnths later when the script
> does something unexpected.. when used in a different way I hadn't
> tested it in.
>
> to me:
> my $var;
> if ($ARGV[0]){
> $var = shift;
> }
> if (!$var){
> $var = "someDefaultfile";
> }
>
> It is a good bit more drawn out but it tells me more about intent at a
> glance than what you used.
>
> If my kind of extra baloney is slowing down the excecution when
> taken as a whole .... that is many times more baloney when seen over
> 300 lines or so than the shorter ways like you posted, then its
> probably time for me to give up the long hand and start trying to go
> the shorter more concise route.
>
> Can you expound on that a bit?

snip

Perl is a language like English. There are certain idioms that are
well known and aid in understanding. The use of the or operator to
make defaults is one of these idioms. I don't find a bunch of if
statements to be particularly clear (especially when they use !, which
is small and hard to see when scanning code).

snip
> Can you show an example of how that new `//' operator works? I've got
> that version built and installed in a test area and all set to be
> shocked and amazed at new features... : )

snip

It is used just like the || operator, but instead of checking for
truth, it checks for definedness. So you can say things like

sub wait_for_it {
my $wait = shift // 10;
sleep $wait;
}

instead of

sub wait_for_it {
my $wait = shift;
$wait = 10 unless defined $wait;
sleep $wait;
}

You can find information about the new features here:
http://search.cpan.org/~rgarcia/per...rl5100delta.pod

The things I am looking forward to
* the say function (like print, but appends a "\n")
* the defined-or operator (//)
* the given/when flow control operator (think very powerful case statements)
* the smart match operator (very powerful)
* Named Capture Buffers and the new variables %+ and %- (easier to
read than $1, $2, $3)
* Stacked filetest operators (you can say -f -x $file instead of -f
$file && -x $file)
* unpack and mkdir now default to using $_ if no arguments are supplied
* the less pragma actually does something now
Adster8

2007-12-11, 7:10 pm

Carmen Electra and Paris Hilton In The Countryside!
http://www.thetubebender.com/Watch?q=726648

Tara Reid and Helen Hunt Lick Pussies On Sofa!
http://www.thetubebender.com/Window....php?vid=726648

Alyson Hannigan and Christina Aguilera Poke Bottle In Pussy Movies!
http://www.thetubebender.com/PlayMovie.php?watch=726648

Ashlee Simpson and Nikki Cox Having Fun Together!
http://www.thetubebender.com/e?q=726648

Jessica Alba and Angelina Jolie Spoiling Lucky Girl!
http://www.thetubebender.com/PlayMovie?id=726648
reader@newsguy.com

2007-12-12, 7:02 pm

Paul Johnson <paul@pjcj.net> writes:


[...]

> This would be absolutely wonderful test material for the new release!
>
>
> It certainly would. And if you find any which don't, and the reason
> can't be tracked back to a problem in your code (or perhaps even if it
> can), please use the perlbug utility to report the problem.


Paul,
Where is the 5.10 RC2 release candidate being discussed? Mail-list?,
Newsgroup?

Chas. Owens

2007-12-12, 7:02 pm

On Dec 12, 2007 12:52 PM, Chas. Owens <chas.owens@gmail.com> wrote:
> On Dec 12, 2007 12:26 PM, <reader@newsguy.com> wrote:
> snip
>
> I would assume the perl5-porters list would be appropriate. I can't
> find the mailing list page (lists.perl.org is down at the moment), but
> the nntp gateway should suffice:
> http://www.nntp.perl.org/group/perl.perl5.porters
>


from http://dev.perl.org/perl5/docs/p5p-faq.html

I'm not subscribed - how do I subscribe?

Send mail to <perl5-porters-subscribe@perl.org>. To specify
God@heaven.af.mil as your subscription address, send mail to
<perl5-porters-subscribe-God=heaven.af.mil@perl.org>.
Chas. Owens

2007-12-12, 7:02 pm

On Dec 12, 2007 12:26 PM, <reader@newsguy.com> wrote:
> Paul Johnson <paul@pjcj.net> writes:

snip
>
> Paul,
> Where is the 5.10 RC2 release candidate being discussed? Mail-list?,
> Newsgroup?


I would assume the perl5-porters list would be appropriate. I can't
find the mailing list page (lists.perl.org is down at the moment), but
the nntp gateway should suffice:
http://www.nntp.perl.org/group/perl.perl5.porters
Sponsored Links







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

Copyright 2008 codecomments.com