Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Strings/Numbers aren't equating properly

by M4ver1k (Novice)
on Feb 21, 2018 at 23:29 UTC ( [id://1209704]=perlquestion: print w/replies, xml ) Need Help??

M4ver1k has asked for the wisdom of the Perl Monks concerning the following question:

Edit: This is fixed. It was my fault...Flawed logic, it took time to work out. Explanation at the bottom of this post.

I'm trying to compare results from an LDAP server to what lives on a MySQL server. Overall it works, right now I'm trying to optimize a part of it. I took the results of an LDAP query returning a single string value to an array '@ldap' which I then sorted alphabetically.

Now I'm doing a search in MySQL, and as I iterate through the results, I'm comparing one column to the '@ldap' array and then I remove any matches out of '@ldap'. The problem is that sometimes, even though strings appear identical, it doesn't count it as a match and so fails to remove the match out of '@ldap', which creates redundant work at the end of the script.

Here's the problematic code:
$sth = $dbh->prepare("select * from table order by mid"); # So +rting alphabetically $sth->execute(); while(my $info = $sth->fetchrow_hashref){ my $count = 0; my $mid = $$info{'mid'}; chomp($mid); my $num = 0; if ($mid =~ /^[0-9]+$/){ # Checks to see if string hap +pens to be only numbers print fh "$mid is a number\n"; $num = 1; # If so, change value } else { print fh "$mid is a string\n"; # Prints to a t +ext file for me to look at. } print "$mid - \$num = $num\n" if ($debug > 0); foreach my $id (@ldap){ chomp($id); # Check to see if we've found a correlating LD +AP entry from MySQL if ($num == 1){ print fh "$mid - $id - Equating as numbers.\n"; last if ($count > 15); if ($mid == $id){ # Check type to see if we have + data on it if ($$info{'type'} ne 'NA'){ # If we do, then remov +e this ID from the list to retry splice @ldap, $count, +1; last; } } } else { print fh "$mid - $id - Equating as strings.\n"; last if ($count > 15); # To drastically shorten during troubleshooting if ($mid eq $id){ # Check type to see if we have + data on it if ($$info{'type'} ne 'NA'){ # If we do, then remov +e this ID from the list to retry splice @ldap, $count, +1; last; } } } $count++; } } $sth->finish;

At first I thought it was because sometimes the strings contain only numbers, so I decided to check if they do contain only numbers, and if so, compare using '==' instead of 'eq'. I also was expecting to be able to use just $$info{'mid'} directly for comparison, so I did my $mid = $$info{'mid'}; for the sake of troubleshooting.

In the file output, regardless of if they equate as strings or numbers, sometimes it just doesn't match when it looks like it should. Now I'm stumped. I'd be grateful for help, thank you!

Edit: It's working now. My flawed logic was here:

if ($$info{'type'} ne 'NA'){ # If we do, then remove this ID from the list to retry splice @ldap, $count, 1; last; }

I ended up having a lot more entries of type 'NA' than I was expecting, and due to work later in the script it ended up making more sense to put those entries into another array to separate out the work. So I changed the logic to this:

if ($$info{'type'} eq 'NA'){ push(@file, $id); } # If we do, then remove this UID from the list to retry splice @ldap, $count, 1; last;
I appreciate everyone's time, thank you.

Replies are listed 'Best First'.
Re: Strings/Numbers aren't equating properly
by dave_the_m (Monsignor) on Feb 21, 2018 at 23:37 UTC
    you've got your == and eq the wrong way round. When $mid's an int, you're using eq and vice-versa

    Dave.

      hahahaha Well that's funny, my bad. I fixed that, but still have the same results. Thanks for taking the time to poke at it.

        Please show the updated code that produces the same problematic results.

Re: Strings/Numbers aren't equating properly
by poj (Abbot) on Feb 22, 2018 at 07:58 UTC

    It could be leading or trailing spaces, add TRIM to the sql and try s/\s//g in place of chomp on the @ldap elements. Use Data::Dumper to inspect the values. For example

    #!/usr/bin/perl use strict; use DBI; use Data::Dumper; my $dbh = get_dbh(); #as required # get mysql records my $sql = "SELECT TRIM(mid),type FROM table WHERE type != 'NA'"; my $sth = $dbh->prepare($sql); $sth->execute(); my %table = (); while (my ($mid,$type) = $sth->fetchrow_array){ $table{$mid} = $type; } #print Dumper \%table; # check ldap records my @ldap = (" 4\r\n"," 5 "," 6 ",7,8,9,1,2,3); #print Dumper \@ldap; my @new_ldap = (); for my $id (@ldap){ #chomp $id; $id =~ s/\s//g; if (exists $table{$id}){ print "[$id] removed\n"; } else { push @new_ldap,$id; } } #print Dumper \@new_ldap;
    update : removed limit of 15 on sql
    poj
      . . . and if the data is really numeric, check to be sure that they are being handed back as numbers. If they are being handed back as strings, "2.0" and "2.00" are not the same string. Next, bear in mind the usual caveats about making exact comparisons of floating-point numbers, which apply to any programming language.
Re: Strings/Numbers aren't equating properly
by karlgoethebier (Abbot) on Feb 24, 2018 at 17:01 UTC

    I couldn't resist to run my famous emacs macro on a buffer with your code:

    Please see perltidy for further information.

    Note that perltidy doesn't delete your comments ;-)

    Best regards, Karl (AKA Dr Wisenheimer)

    P.S.: See also bareword filehandles, qq and say.

    «The Crux of the Biscuit is the Apostrophe»

    perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1209704]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (5)
As of 2024-03-29 13:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found