Problem with loop control LAST exiting prematurely

R

Rodion

Hi!
I got into a problem with looking up stuff in hasheshes, the sub is
supposed to check if $data is in the hash, and when found exit the loop,
as there is no need to go through the rest of the hash.
Only for some reason it exits immediately :?

the code:
--------
CODECHECK: while ( ($k,$v) = each %{$cb{$cbName}}) {
switch ($test){
case 'numbers' {
if ($data==$k){
$found=1;
last CODECHECK if ($found==1);
}
}
case 'text' {
if ($data eq $k){
$found=1;
last CODECHECK if ($found==1);
}
}
}
}
 
W

Willem

Rodion wrote:
) Hi!
) I got into a problem with looking up stuff in hasheshes, the sub is
) supposed to check if $data is in the hash, and when found exit the loop,
) as there is no need to go through the rest of the hash.
) Only for some reason it exits immediately :?
)
) the code:
) --------
) CODECHECK: while ( ($k,$v) = each %{$cb{$cbName}}) {
) switch ($test){
) case 'numbers' {
) if ($data==$k){
) $found=1;
) last CODECHECK if ($found==1);
) }
) }
) case 'text' {
) if ($data eq $k){
) $found=1;
) last CODECHECK if ($found==1);
) }
) }
) }
) }
) -----------
) The problem is that last exits the loop before $found is set which
) shouldnt happen.

How do you know that it's the 'last' that is exiting the loop ?


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
R

Rodion

Jednom davno, ne znam vise kad, Willem duboko zamisljen/a rece:
Rodion wrote:
) The problem is that last exits the loop before $found is set which
) shouldnt happen.

How do you know that it's the 'last' that is exiting the loop ?

Easily, if I comment it out, it works correctly, albait slowly as it has
to go through the whole hash which is unnaceptable :(
 
J

John W. Krahn

Rodion said:
Hi!
I got into a problem with looking up stuff in hasheshes, the sub is
supposed to check if $data is in the hash, and when found exit the loop,
as there is no need to go through the rest of the hash.
Only for some reason it exits immediately :?

the code:
--------
CODECHECK: while ( ($k,$v) = each %{$cb{$cbName}}) {
switch ($test){
case 'numbers' {
if ($data==$k){
$found=1;
last CODECHECK if ($found==1);
}
}
case 'text' {
if ($data eq $k){
$found=1;
last CODECHECK if ($found==1);
}
}
}
}

Couldn't you just write that as:

$found = 1 if exists $cb{$cbName}{$data};


John
 
R

Rodion

Jednom davno, ne znam vise kad, John W. Krahn duboko zamisljen/a rece:

Couldn't you just write that as:

$found = 1 if exists $cb{$cbName}{$data};

Well I get the same problem, some cases arent found in the hash key...
I think it's a data type problem...confusing...
 
R

Rodion

Jednom davno, ne znam vise kad, John W. Krahn duboko zamisljen/a rece:
Couldn't you just write that as:

$found = 1 if exists $cb{$cbName}{$data};

Well, I have to thank you for putting me on the right track!

There was a problem with some numeric data having prefixed zeroes while
some of the hash keys did not so there could be no match ( 0567 != 567).
But I'm still confused why the LAST was triggered before a match was
$found?

In any case the code is now much leaner :)

I heart Perl!
 
X

xhoster

Rodion said:
Jednom davno, ne znam vise kad, John W. Krahn duboko zamisljen/a rece:


Well, I have to thank you for putting me on the right track!

There was a problem with some numeric data having prefixed zeroes while
some of the hash keys did not so there could be no match ( 0567 != 567).
But I'm still confused why the LAST was triggered before a match was
$found?

I rather doubt that it was doing that. If you want to pursue the matter,
post a complete, runnable script to illustrate this. Otherwise I'll assume
you are misinterpreting something.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
 
R

Rodion

Jednom davno, ne znam vise kad, (e-mail address removed) duboko zamisljen/a
rece:
I rather doubt that it was doing that. If you want to pursue the matter,
post a complete, runnable script to illustrate this. Otherwise I'll assume
you are misinterpreting something.

Well, I'm most certanly misundrestanding something, but I'd like to know
what, so I don't make the same mistake twice :/

The following subrutine works correctly (and slowly) if the lines with
LAST are commented out.

Code:
sub checkCB{
my $cbName=$_[0];
my $data=$_[1];
my ($k,$v);
my $found;
my $g=0;
my $checked;
my $test='text';

print "looking for [$data] in [$cbName] control: ";

#----numbers exception
if ($data=~/^\d{1,30}$/){
$data=int($data);
$test='numbers';
}

CODECHECK: while ( ($k,$v) = each %{$cb{$cbName}}) {
#print $g++."\n";
switch ($test){
case 'numbers' {
if ($data==$k){
$found=1;
#last CODECHECK if ($found==1);
}
}
case 'text' {
if ($data eq $k){
$found=1;
#last CODECHECK if ($found==1);
}
}
}
}

return $found;
}
 
A

Andrew DeFaria

Rodion said:
Jednom davno, ne znam vise kad, (e-mail address removed) duboko zamisljen/a
rece:
I rather doubt that it was doing that. If you want to pursue the matter,
post a complete, runnable script to illustrate this. Otherwise I'll
assume
you are misinterpreting something.
Well, I'm most certanly misundrestanding something, but I'd like to know
what, so I don't make the same mistake twice :/

The following subrutine works correctly (and slowly) if the lines with
LAST are commented out.

Code:

sub checkCB{
my $cbName=$_[0];
my $data=$_[1];
my ($k,$v);
my $found;
my $g=0;
my $checked;
my $test='text';

print "looking for [$data] in [$cbName] control: ";

#----numbers exception
if ($data=~/^\d{1,30}$/){
$data=int($data);
$test='numbers';
}

CODECHECK: while ( ($k,$v) = each %{$cb{$cbName}}) {
#print $g++."\n";
switch ($test){
case 'numbers' {
if ($data==$k){
$found=1;
#last CODECHECK if ($found==1);
}
}
case 'text' {
if ($data eq $k){
$found=1;
#last CODECHECK if ($found==1);
}
}
}
}

return $found;
}
Ever try using Perl's debugger? Change some of the "last CODECHECK if
($found==1)"'s to a full if statement just so you can set break points
in the debugger and then examine the execution and the data in the
variables as this subroutine operates. You will learn a ton about how
Perl works, how your code works or does not work and will not have to
resort to having others solve your problems. Try it sometime - seriously!
 
X

xhoster

Rodion said:
Jednom davno, ne znam vise kad, (e-mail address removed) duboko zamisljen/a
rece:


Well, I'm most certanly misundrestanding something, but I'd like to know
what, so I don't make the same mistake twice :/

The following subrutine works correctly (and slowly) if the lines with
LAST are commented out.

Global symbol "%cb" requires explicit package name...

And if I make up my own values for %cb, then I don't see what you
say you see.

Please post COMPLETE, RUNNABLE code which illustrates that which is to
be illustrated.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.
 
B

Brian Helterline

Rodion said:
Jednom davno, ne znam vise kad, John W. Krahn duboko zamisljen/a rece:


Well, I have to thank you for putting me on the right track!

There was a problem with some numeric data having prefixed zeroes while
some of the hash keys did not so there could be no match ( 0567 != 567).

If you are doing the testing using numeric comparison, then they are equal.

print "equal" if '0567' == '567';
 
P

Peter J. Holzer

Jednom davno, ne znam vise kad, (e-mail address removed) duboko zamisljen/a
rece:

Try to canonicalize the data.
Well, I'm most certanly misundrestanding something, but I'd like to know
what, so I don't make the same mistake twice :/

The following subrutine works correctly (and slowly) if the lines with
LAST are commented out.

How does it not work correctly if these lines are not commented out?

Please post an example which demonstrates the problem.
Code:
sub checkCB{
my $cbName=$_[0];
my $data=$_[1];
my ($k,$v);
my $found;
my $g=0;
my $checked;
my $test='text';

print "looking for [$data] in [$cbName] control: ";

#----numbers exception
if ($data=~/^\d{1,30}$/){
$data=int($data);
$test='numbers';
}

CODECHECK: while ( ($k,$v) = each %{$cb{$cbName}}) {
#print $g++."\n";
switch ($test){

Don't use switch. It is rather buggy and introduces problems which are
hard to find.
case 'numbers' {
if ($data==$k){
$found=1;
#last CODECHECK if ($found==1);

$found is always 1 here (you just set it to one), so this is equivalent
to "last CODECHECK;". However, that seems to be what you want.
}
}
case 'text' {
if ($data eq $k){
$found=1;
#last CODECHECK if ($found==1);

Same here.
 
A

Andrew DeFaria

Frank said:
You're right, but it depends on the shell.

% perl
print "equal\n" if '0567' == '375'
^D
%

% perl
print "equal\n" if '0567' == '567'
^D
equal
%
Huh? How are the above two different?
 
R

Rodion

Jednom davno, ne znam vise kad, Peter J. Holzer duboko zamisljen/a rece:
Try to canonicalize the data.

The problem was in my data which became clear when I ditched that ugly
sub with a more sensible:

$found = 1 if exists $cb{$cbName}{$data};

and added a few checks for the data.
Don't use switch. It is rather buggy and introduces problems which are
hard to find.

That sucks. I depend on switch in this for the main part of the program.
Is it documented?
$found is always 1 here (you just set it to one), so this is equivalent
to "last CODECHECK;". However, that seems to be what you want.

Yes I wrote a lot of silly stuff in a hurry trying to see what is
happening :/

Thanks for the help :)
 
U

Uri Guttman

R> That sucks. I depend on switch in this for the main part of the program.
R> Is it documented?

no, switch sucks. perl 5.10 has a proper builtin called given/when. and
for simple string cases a dispatch table is much better. google for that
phrase in this group as it has been discussed many times.

uri
 
B

Brian Helterline

Lawrence said:
Does not print "equal"

It does on my system:


C:\>perl -le "print 'equal' if '0567' == '567'"
equal

C:\>perl -v

This is perl, v5.8.8 built for MSWin32-x86-multi-thread
(with 33 registered patches, see perl -V for more detail)
 
T

Ted Zlatanov

FS> $ perldoc -f dec
FS> No documentation for perl function `dec' found

Obviously you needed "perldoc -f DEC" :)

Ted
 

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,769
Messages
2,569,581
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top