Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > String comparison operator trouble

Reply
Thread Tools

String comparison operator trouble

 
 
J.D. Baldwin
Guest
Posts: n/a
 
      07-16-2008


I solved my problem by rewriting, but I'm wondering why I am getting errors
with respect to 'ne' and 'eq' operators.

This code works fine (Perl 5.8.:

$ cat minimal.pl
#!/opt/gnu/bin/perl

use warnings;
use strict;

my $VAL = 'xyz';

my @foo = ( 'abc', 'def', 'ghi', 'xyz', 'jkl', 'xyz', 'uvw' );

foreach my $item ( @foo )
{
next if ( $item ne $VAL );

print "$item\n";
}
$ ./minimal.pl
xyz
xyz


But if I add a test for 'undef' I get warnings:

$ cat ./minimal2.pl
#!/opt/gnu/bin/perl

use warnings;
use strict;

my $VAL = 'xyz';

my @foo = ( 'abc', 'def', 'ghi', 'xyz', 'jkl', 'xyz', 'uvw' );

foreach my $item ( @foo )
{
next if ( undef $item ) or ( $item ne $VAL );

print "$item\n";
}
$ ./minimal2.pl
Use of uninitialized value in string ne at ./minimal2.pl line 12.
Use of uninitialized value in string ne at ./minimal2.pl line 12.
Use of uninitialized value in string ne at ./minimal2.pl line 12.
Use of uninitialized value in string ne at ./minimal2.pl line 12.
Use of uninitialized value in string ne at ./minimal2.pl line 12.
Use of uninitialized value in string ne at ./minimal2.pl line 12.
Use of uninitialized value in string ne at ./minimal2.pl line 12.

Even weirder if I try 'eq':

$ cat ./minimal3.pl
#!/opt/gnu/bin/perl

use warnings;
use strict;

my $VAL = 'xyz';

my @foo = ( 'abc', 'def', 'ghi', 'xyz', 'jkl', 'xyz', 'uvw' );

foreach my $item ( @foo )
{
next if ( undef $item ) or ( $item eq $VAL );

print "$item\n";
}
$ ./minimal3.pl
Use of uninitialized value in string eq at ./minimal3.pl line 12.
Use of uninitialized value in concatenation (.) or string at ./minimal3.pl line 14.

Use of uninitialized value in string eq at ./minimal3.pl line 12.
Use of uninitialized value in concatenation (.) or string at ./minimal3.pl line 14.

Use of uninitialized value in string eq at ./minimal3.pl line 12.
Use of uninitialized value in concatenation (.) or string at ./minimal3.pl line 14.

Use of uninitialized value in string eq at ./minimal3.pl line 12.
Use of uninitialized value in concatenation (.) or string at ./minimal3.pl line 14.

Use of uninitialized value in string eq at ./minimal3.pl line 12.
Use of uninitialized value in concatenation (.) or string at ./minimal3.pl line 14.

Use of uninitialized value in string eq at ./minimal3.pl line 12.
Use of uninitialized value in concatenation (.) or string at ./minimal3.pl line 14.

Use of uninitialized value in string eq at ./minimal3.pl line 12.
Use of uninitialized value in concatenation (.) or string at ./minimal3.pl line 14.

Can anyone explain to me why I see this behavior? It seems like a
perfectly normal chained test.
--
_+_ From the catapult of |If anyone disagrees with any statement I make, I
_|70|___=}- J.D. Baldwin |am quite prepared not only to retract it, but also
\ / |to deny under oath that I ever made it. -T. Lehrer
***~~~~-----------------------------------------------------------------------
 
Reply With Quote
 
 
 
 
Jens Thoms Toerring
Guest
Posts: n/a
 
      07-16-2008
J.D. Baldwin <> wrote:
> I solved my problem by rewriting, but I'm wondering why I am getting errors
> with respect to 'ne' and 'eq' operators.


> This code works fine (Perl 5.8.:


> $ cat minimal.pl
> #!/opt/gnu/bin/perl
>
> use warnings;
> use strict;
>
> my $VAL = 'xyz';
>
> my @foo = ( 'abc', 'def', 'ghi', 'xyz', 'jkl', 'xyz', 'uvw' );
>
> foreach my $item ( @foo )
> {
> next if ( $item ne $VAL );
>
> print "$item\n";
> }
> $ ./minimal.pl
> xyz
> xyz



> But if I add a test for 'undef' I get warnings:


> $ cat ./minimal2.pl
> #!/opt/gnu/bin/perl
>
> use warnings;
> use strict;
>
> my $VAL = 'xyz';
>
> my @foo = ( 'abc', 'def', 'ghi', 'xyz', 'jkl', 'xyz', 'uvw' );
>
> foreach my $item ( @foo )
> {
> next if ( undef $item ) or ( $item ne $VAL );


'undef' is an unary operator that undefines what it's applied to,
not a test if the variable is undefined. I guess you meant to use

next if ! defined $item || $item ne $VAL;
or
next unless defined $item && $item eq $val;

Regards, Jens
--
\ Jens Thoms Toerring ___
\__________________________ http://toerring.de
 
Reply With Quote
 
 
 
 
szr
Guest
Posts: n/a
 
      07-16-2008
J.D. Baldwin wrote:
> I solved my problem by rewriting, but I'm wondering why I am getting
> errors
> with respect to 'ne' and 'eq' operators.


[...]

> But if I add a test for 'undef' I get warnings:
>
> $ cat ./minimal2.pl
> #!/opt/gnu/bin/perl
>
> use warnings;
> use strict;
>
> my $VAL = 'xyz';
>
> my @foo = ( 'abc', 'def', 'ghi', 'xyz', 'jkl', 'xyz', 'uvw' );
>
> foreach my $item ( @foo )
> {
> next if ( undef $item ) or ( $item ne $VAL );
>
> print "$item\n";
> }
> $ ./minimal2.pl
> Use of uninitialized value in string ne at ./minimal2.pl line 12.
> Use of uninitialized value in string ne at ./minimal2.pl line 12.
> Use of uninitialized value in string ne at ./minimal2.pl line 12.
> Use of uninitialized value in string ne at ./minimal2.pl line 12.
> Use of uninitialized value in string ne at ./minimal2.pl line 12.
> Use of uninitialized value in string ne at ./minimal2.pl line 12.
> Use of uninitialized value in string ne at ./minimal2.pl line 12.


The problem is you're calling undef $item which undefines $item.

What you want to use instead is:

next if ( ! defined $item ) or ( $item ne $VAL );


defined() will tell you if a scalar has been defined or so. For arrays
and hashes, drop the define, as if(@array) and if(%hash) will return
true only if there are items within.

Also see: perldoc -f defined and also: perldoc -f undef
This will help you learn what undef() is used for and about using
defined().

How this helps.

--
szr


 
Reply With Quote
 
Dave B
Guest
Posts: n/a
 
      07-16-2008
J.D. Baldwin wrote:

> next if ( undef $item )


$item == undef

or

!defined($item)

"perldoc -f undef" to see why your command does not do what you want, and
the warnings you get are expected.

--
D.
 
Reply With Quote
 
Jim Gibson
Guest
Posts: n/a
 
      07-16-2008
In article <g5l4ig$c54$>, J.D. Baldwin
<> wrote:

> I solved my problem by rewriting, but I'm wondering why I am getting errors
> with respect to 'ne' and 'eq' operators.
>


> But if I add a test for 'undef' I get warnings:
>
> $ cat ./minimal2.pl
> #!/opt/gnu/bin/perl
>
> use warnings;
> use strict;
>
> my $VAL = 'xyz';
>
> my @foo = ( 'abc', 'def', 'ghi', 'xyz', 'jkl', 'xyz', 'uvw' );
>
> foreach my $item ( @foo )
> {
> next if ( undef $item ) or ( $item ne $VAL );
>
> print "$item\n";
> }


The test for defined-ness is defined, not undef. The operator undef
sets the variable to undef.

perldoc -f defined

--
Jim Gibson
 
Reply With Quote
 
John W. Krahn
Guest
Posts: n/a
 
      07-16-2008
Dave B wrote:
> J.D. Baldwin wrote:
>
>> next if ( undef $item )

>
> $item == undef


That won't work correctly either.

$ perl -le'
for my $item ( 0, 1, "two" ) {
print $item if $item == undef;
}
'
0
two


John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall
 
Reply With Quote
 
Uri Guttman
Guest
Posts: n/a
 
      07-16-2008
>>>>> "DB" == Dave B <> writes:

DB> J.D. Baldwin wrote:
>> next if ( undef $item )


DB> $item == undef

very wrong. the only way to test for definedness is with defined. wipe
that idiom out of your brain. just to make it clear, try that with any
false value in $item (and enable warnings too for more results).

uri

--
Uri Guttman ------ -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Free Perl Training --- http://perlhunter.com/college.html ---------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
 
Reply With Quote
 
Jürgen Exner
Guest
Posts: n/a
 
      07-16-2008
Dave B <> wrote:
>J.D. Baldwin wrote:
>
>> next if ( undef $item )

>
>$item == undef


This doesn't do what you seem to think it is doing.

First of all it will trigger two warnings (for generic $item):
- Use of uninitialized value in numeric eq (==)[*]
- Argument "...." isn't numeric in numeric eq (==) [**]
[*]: because undef is not initialized, surprise, surprise
[**]: because in the generic case $item may contain a string or -gasp-
be undefined instead of number.

And second the numerical value of undef is 0 and therefore this
comparison will yield true whenever the numerical value of $item is 0,
in particular also when $item contains a string that does not start with
a number.

jue
 
Reply With Quote
 
J.D. Baldwin
Guest
Posts: n/a
 
      07-16-2008

In the previous article, Jens Thoms Toerring <> wrote:
> 'undef' is an unary operator that undefines what it's applied to,
> not a test if the variable is undefined. I guess you meant to use


<slaps forehead>

So much for focusing on the comparison operator.

Thank you (and you others) for setting me straight on this.

undef ne ( ! defined ). Got it.
--
_+_ From the catapult of |If anyone disagrees with any statement I make, I
_|70|___=}- J.D. Baldwin |am quite prepared not only to retract it, but also
\ / |to deny under oath that I ever made it. -T. Lehrer
***~~~~-----------------------------------------------------------------------
 
Reply With Quote
 
Dave B
Guest
Posts: n/a
 
      07-16-2008
Jürgen Exner wrote:

> Dave B <> wrote:
>> J.D. Baldwin wrote:
>>
>>> next if ( undef $item )

>> $item == undef

>
> This doesn't do what you seem to think it is doing.


Thank you, John and Uri for correcting me on this. It seemed to work in a
quick and simple test like perl -e 'print "ok" if $var == undef;' but, as
you correctly point out, that idiom cannot be used in general.

Thanks

--
D.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Comparison of 2 files and generating the output based on comparison Deepu Perl Misc 1 02-07-2011 03:09 PM
False Positives From String Comparison using string.Equals() Smithers ASP .Net 12 07-07-2009 01:23 AM
Price Comparison Service. Best Deal. Special Coupon atBest-Price-Comparison.com rapee Digital Photography 0 03-14-2008 06:46 AM
Is there systematic performance comparison of std::string and c style string? yu_kuo@sina.com C++ 21 08-18-2007 04:32 PM
std::map< MyString, MyString > comparison operator? jstanforth C++ 13 04-13-2005 08:03 PM



Advertisments