Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl qr// operation

Tags:

perl

i have a question about Perl qr operator:

#!/usr/bin/perl -w
&mysplit("a:b:c", /:/);  
sub mysplit {  
    my($str, $pattern) = @_;  
    my @arr = split $pattern, $str;  
    print "@arr\n";  
}

The result is:

Use of uninitialized value $_ in pattern match (m//) at ./test.pl line 3.
Use of uninitialized value $pattern in regexp compilation at ./test.pl line 7.

But when i used: &mysplit("a:b:c", qr/:/);, it is ok.
So, i want to know what the difference betweenqr// and m//?
Why $_ is related here?
And why it is ok in the case split /:/, "a:b:c";?

Thank you in advance!

like image 713
ruanhao Avatar asked Dec 21 '22 05:12

ruanhao


1 Answers

Well, your problem here is that this expression:

/:/

really means this:

$_ =~ /:/

Which is why perl is reporting an uninitialized error on $_.

The qr() operator does not have this shortcut, which is why it by itself is an acceptable statement in this case.

So, to be clear: Your statement:

&mysplit("a:b:c", /:/);

Really means this:

&mysplit("a:b:c", $_ =~ /:/);

Since $_ is undefined, the regex match returns the empty list. It could have returned the empty string, but since you have list context, it returns the empty list, making the error a little bit more obvious.

Because it returns the empty list, only one argument is passed to mysplit(), which is why you get the second warning:

Use of uninitialized value $pattern in regexp compilation at ./test.pl line 7.

If the empty string had been passed, this part of the error would have been silent.

Also, you should know that using ampersand & in front of your subroutine calls have a specific function. You should not use it unless you intend to use that function. The various ways of calling a sub are these, as documented in perldoc perlsub:

NAME(LIST);  # & is optional with parentheses.
NAME LIST;   # Parentheses optional if predeclared/imported.
&NAME(LIST); # Circumvent prototypes.
&NAME;       # Makes current @_ visible to called subroutine.

The default way is the top one, in your case: mysplit(...)

like image 56
TLP Avatar answered Jan 13 '23 19:01

TLP