Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

default @_ array collection , is it readonly 2

Status
Not open for further replies.

1DMF

Programmer
Jan 18, 2005
8,795
GB
I understand that you cannot change CGI->param vars , but I thought the @_ collection was changeable ie
Code:
$_[0] = "My Value";

But I have found trying to do a text comparison wasn't working...
Code:
if($_[1] =~ /c/gi) { do whatever;}

it only works if I make a variable = the @_ value first like so
Code:
my $var = $_[1];
if($var =~ /c/gi) { do whatever;}

What am I missing here?

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!
 
I'm not sure it's anything to do with the @_ collection as I have the smae problem with the following
Code:
if($user =~ /c/gi || $ADMIN){
    $template->param( 'admin' => 1 );    
}

This doesn't work with following criteria....
Code:
$user = CQ00992211;
$ADMIN = 0;
But if I change the if statement to the following...
Code:
if(uc($user) =~ /c/gi || $ADMIN){
    $template->param( 'admin' => 1 );    
}

it works fine?

Why on earth is it behaving like this, isn't the gi switch suppose to mean 'global / ignore case' ?

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!
 
First, are you sure you want

Code:
$user = CQ00992211;

and not

Code:
$user = 'CQ00992211';

? If you were using strict, perl wouldn't let you do this. You should always start your scripts with

Code:
#/path/to/perl
use strict;

It will save you a lot of trouble. Second, this prints "foo" for me. Is there something else going on in the program?

Code:
#!/usr/bin/perl
use strict;

my $user = 'CQ00992211';
if($user =~ /c/i) {
    print "foo\n";
}

--
 
for get the strict and quotes i use strict and the missing quote was simply a typo.

I always use
Code:
use CGI::Carp qw/fatalsToBrowser warningsToBrowser/;
use warnings;
use strict;

Obviously my $user = xyz isn't a real line of code $user = who ever is logged on, it was merly an example.

Also your example doesn't include the || $ADMIN part, and I beleive this is some weird thing to do with using perl matching and an OR with an if.

It's all a bit bizzarre, yet wrapping the $user in uc($user) fixes the problem.






"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!
 
I understand that $user would most likely not be assigned a text string like that in the real world. However, if you've narrowed down your problem from a larger script and put it in a smaller script to debug it, then $user could in fact be assigned a string for debugging purposes. I was just going by what was given in the problem description.

I took out the $ADMIN part because it doesn't help solve your problem. As far as I can tell, you're trying to figure out why the matching operator isn't working the way you expect -- adding || to the if statement just adds complications.

Try copy-pasting the code I posted previously and see if it works. Or, if you really want, copy this:

Code:
#!/usr/bin/perl
use strict;

my $user = 'CQ00992211';
my $ADMIN = 0;

if($user =~ /c/i || $ADMIN) {
    print "foo\n";
}

--
 
sycoogtit's code from the last post works as expected for me. Perl 5.8.8 on Linux.
 
I appreciate your help, but it's not as simple as just using your code, as it does work and so does my code the first time used in the script, the second time however it doesn't.

the other bizzare thing is as I said, is it works fine if you put the uc($user) function round the var, but without it it wasn't being triggered, which doesn't make sense as I am using the 'i' switch to ignore case.

why would using the uc method make this difference?

this is the exact code being used, near the top of the script I use this...

Code:
#Get any existing comps relative to login 
if($user =~ /c/gi || $ADMIN){
    # get AR No!
    my ($arno, $ext) = split(/-/,$user);
    # Remove 'C'
    $arno =~ s/c//gi;
    $where = "Adv_MemNo like '$arno-%'";
}
else{
    $where = "Adv_MemNo = '$user'";
}


then later on in the script I use this for another test...
Code:
if($user =~ /c/gi || $ADMIN){
    $template->param( 'admin' => 1 );    
}
and it wasn't being triggered, as soon as I changed it to this...
Code:
if([b]uc($user)[/b] =~ /c/gi || $ADMIN){
    $template->param( 'admin' => 1 );    
}
it worked.

and notice how I've forced it to uppercase and then check lower ignoring case and it worked.

I'm not making this up guys!



"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!
 
right if you don't beleive me try this , what result do you get ?

Code:
#!/usr/bin/perl

######################
# Set Error Trapping #
######################

use CGI::Carp qw(fatalsToBrowser warningsToBrowser); 
use warnings;
use strict;
    
# Set path to user modules
use FindBin qw($Bin);
use lib "$Bin";

my $user = "cq123456789-001";
my $where;

my $ADMIN = 0;

#Get any existing comps relative to login 
if($user =~ /c/gi || $ADMIN){
    # get AR No!
    my ($arno, $ext) = split(/-/,$user);
    # Remove 'C'
    $arno =~ s/c//gi;
    $where = "Adv_MemNo like '$arno-%'";
}

if($user =~ /c/gi || $ADMIN){
    die "matched it";    
}


die "failed to match";

and if you change the second if statement to...
Code:
if([b]uc($user)[/b] =~ /c/gi || $ADMIN){
    die "matched it";    
}

what do you get?

is this bizzare or what!

or am I the only one with this wierd behaviour?

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!
 
I can confirm the behaviour being strange-looking at first glance. Taking a look now.
 
I suspect it's to do with the way Perl optimises regexps.

Short answer: get rid of the /g switch. You don't gain anything from it as you're only checking to see if the string contains a letter 'c'.

If you apply a regexp with a 'g' to the same string in a loop, each iteration will start where the last left off, i.e.:
Code:
my $string = 'ccc';
while( $string =~ /c/g ) {
   print "Found a c\n";
}
That loop will run 3 times (once for each match). If you leave out the 'g' then it runs forever, as it keeps looking from the start of the string for a single match).

In your case, you're not using a loop, but you are using the same regexp (with a 'g') on the same string twice. I suspect (though I'm not certain) that something similar is going on.
 
1DMF, it's not that we don't believe you. We're trying to help you, but were somewhat limited given the information you had supplied. Thanks for supplying all of your code this time.

Since you just want to see if any 'c' characters are in the string, you don't need the g option for the match. If you take off the g from your match, it works.

--
 
Thanks Ishnid, glad i'm not going mad!

So the g is 'greedy' is that right? meaning keep going even after matching.

because the string being checked has the first char as a 'c' , your saying the next check is starting from the second char and so is not matching because of some internal pointer that perl uses with the greedy switch.

and I guess using the upper case method on the string changes its contents or puts it in an internal temp var and so the pointer starts from the beginning.

Man i'm so glad people like you hang around this forum, this bug was doing my head in!

As always Ishnid you're a gentleman and a schollar, have a great weekend!

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!
 
No greedy, no. It is for a global match, as you said earlier. It basically tells Perl that you want to find all the matches in the string. It obviously can't do that if it's finding the same match (the first one) all the time, so each time it's asked to do the same match it starts after where it left off the last time. Leaving off the 'g' will result it starting at the beginning every time.

You're exactly right on the "uc" part. Since it's applying the regexp to a different string, it has to start at the beginning to find the first match. If you were doing that match a third time, doing a "uc" probably wouldn't work for the third one.
 
Got ya!

greedy vs global , is there a difference, I thought 'greedy' meant don't stop just coz you matched.

IE.

if I used
Code:
$user =~ s/0//g;

That would remove all zero's , I don't need to loop the string to make it step through each itteration.

or is 'g' for matching different than the 'g' for substitution?

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!
 
It will remove all the 0 characters because it's global!

Greediness is to do with quantifiers in regexps (i.e. the difference between .* and .*?)
 
Yes but the point i'mt rying to make is this...

try this code...

Code:
my $string = 'ccc';
while( $string =~ /c/g ) {
   print "Found a c\n";
}

while( $string =~ s/c//g ) {
   print "Replaced a c\n";
}

the first prints 'Found a c' 3 times the second only prints 'Replaced a c' once.

so therefore I have to deduce there is a difference between replace and match when using the g.

I don't want to confuse the issue over g=greedy or g=global, I accept it's global and I was incorrectly using the word greedy, I had correctly qualified the switch definition in my original post.

I was trying to explain or visualise what was hapening using a word i'd seen else where (ok missuse of word!).

I'm just trying to understand how 'g' works differently between matching and substitution.


"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!
 
all of the substitutions occur in the conditional part of the "while" loop. The expression part is not evaluated until all the c's have been removed. I can't explain why that is, but that is whats happening.

------------------------------------------
- Kevin, perl coder unexceptional! [wiggle]
 
Still not 100% sure what you just said, but appreciate the attempt to explain.

At least I can now see how s/ vs m/ works and won't (well hopefully) get tripped up by it again, that was one bug definately worthy of the saying 'couldn't see the wood for the trees!'

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!
 
Hey Keith,

No $ADMIN is a global var which is set else where in the script, it's a flag that tells me whether the person logged on is an 'Administrator' or not.

It's an internal thing, you see you can be just an Admin, or you can be an adviser that has Admin privilages, or you could be a 'Controller' that is given 'SOME' Admin privilages but not all (hence looking for the 'c')

Are you confused yet ;-)

"In complete darkness we are all the same, only our knowledge and wisdom separates us, don't let your eyes deceive you."

"If a shortcut was meant to be easy, it wouldn't be a shortcut, it would be the way!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top