How these $1 and $2 is decided?

Y

yl

Could anyone help explain this line of code?
$_->[/^(?>(.)?(.)+.*)(?!\1)(??{print(($1..$2)[15,4,17,11])})/]

I think it can be divided into 3 parts
1. (?>(.)?(.)+.*)
2. (?!\1)
3. (??{print(($1..$2)[15,4,17,11])})
and the 3rd part will print 'PERL'. But I got no idea how the variables
$1 and $2 was decided to form an array including 'A'..'Z' (though $2 is
not 'Z').

Another question is that $_ is undef at program start, how could it
become an array reference?

Thanks.
 
J

John W. Krahn

yl said:
Could anyone help explain this line of code?
$_->[/^(?>(.)?(.)+.*)(?!\1)(??{print(($1..$2)[15,4,17,11])})/]

I think it can be divided into 3 parts
1. (?>(.)?(.)+.*)
2. (?!\1)
3. (??{print(($1..$2)[15,4,17,11])})
and the 3rd part will print 'PERL'. But I got no idea how the variables
$1 and $2 was decided to form an array including 'A'..'Z' (though $2 is
not 'Z').

$_->[] autovivifies an array reference so $_ becomes a text string something
like ARRAY(0x12345678) which the regex operates on. ^(?>(.)?(.)+.*)(?!\1)
puts 'A' in $1 and 'R' in $2 giving the list 'A' .. 'R' from which the letters
'P', 'E', 'R' and 'L' are sliced.
Another question is that $_ is undef at program start, how could it
become an array reference?

Autovivification.


John
 
Y

yl

John W. Krahn 寫é“:
$_->[] autovivifies an array reference so $_ becomes a text string something
like ARRAY(0x12345678) which the regex operates on. ^(?>(.)?(.)+.*)(?!\1)

The $_->[/regex/] thing looks quite strange to me. I never thought a
regex can be placed in a bracket like this. Is it a useful expression
that I can use in many situations or just for demonstration of an
advanced Perl skill?

Thanks
 
J

John W. Krahn

yl said:
John W. Krahn 寫é“:
$_->[] autovivifies an array reference so $_ becomes a text string something
like ARRAY(0x12345678) which the regex operates on. ^(?>(.)?(.)+.*)(?!\1)

The $_->[/regex/] thing looks quite strange to me. I never thought a
regex can be placed in a bracket like this. Is it a useful expression
that I can use in many situations or just for demonstration of an
advanced Perl skill?

In the example the regex wasn't used for its return value but for the side
effect of the print function.

An example of a useful use of a regex in an array slice:

my @array = 'a' .. 'z';

$_ = ' 14 1 5 20 18 2 0 19 4 ';

print @a[ /\d+/g ], "\n";



John
 
I

Ilya Zakharevich

[A complimentary Cc of this posting was sent to
John W. Krahn
yl said:
Could anyone help explain this line of code?
$_->[/^(?>(.)?(.)+.*)(?!\1)(??{print(($1..$2)[15,4,17,11])})/]

I think it can be divided into 3 parts
1. (?>(.)?(.)+.*)
2. (?!\1)
3. (??{print(($1..$2)[15,4,17,11])})
and the 3rd part will print 'PERL'. But I got no idea how the variables
$1 and $2 was decided to form an array including 'A'..'Z' (though $2 is
not 'Z').

$_->[] autovivifies an array reference so $_ becomes a text string something
like ARRAY(0x12345678) which the regex operates on. ^(?>(.)?(.)+.*)(?!\1)
puts 'A' in $1 and 'R' in $2 giving the list 'A' .. 'R' from which the letters

Are you sure? Actually, $2 is ')'.

perl -wle "[1] =~ /^(?>(.)?(.)+.*)(?!\1)/ and print $2"
)

Looks like the .. operator (as opposed to ++ !!!) has alphanumeric
*output*, but arbitrary *input*: here 'A' .. ')' is the same as 'A' .. 'Z'.
Probably won't be so on EBCDIC.

Hope this helps,
Ilya
 
A

Anno Siegel

John W. Krahn said:
yl said:
John W. Krahn 寫é“:
$_->[] autovivifies an array reference so $_ becomes a text string something
like ARRAY(0x12345678) which the regex operates on. ^(?>(.)?(.)+.*)(?!\1)

The $_->[/regex/] thing looks quite strange to me. I never thought a
regex can be placed in a bracket like this. Is it a useful expression
that I can use in many situations or just for demonstration of an
advanced Perl skill?

In the example the regex wasn't used for its return value but for the side
effect of the print function.

An example of a useful use of a regex in an array slice:

my @array = 'a' .. 'z'; ^^^^^

$_ = ' 14 1 5 20 18 2 0 19 4 ';

print @a[ /\d+/g ], "\n";
^
Anno
 
J

John W. Krahn

Anno said:
John W. Krahn said:
yl said:
John W. Krahn 寫é“:

$_->[] autovivifies an array reference so $_ becomes a text string something
like ARRAY(0x12345678) which the regex operates on. ^(?>(.)?(.)+.*)(?!\1)
The $_->[/regex/] thing looks quite strange to me. I never thought a
regex can be placed in a bracket like this. Is it a useful expression
that I can use in many situations or just for demonstration of an
advanced Perl skill?
In the example the regex wasn't used for its return value but for the side
effect of the print function.

An example of a useful use of a regex in an array slice:

my @array = 'a' .. 'z'; ^^^^^
$_ = ' 14 1 5 20 18 2 0 19 4 ';

print @a[ /\d+/g ], "\n";
^

Oops, sorry, I copied and pasted the wrong code, it should be:

my @array = 'a' .. 'z';

$_ = ' 14 1 5 20 18 2 0 19 4 ';

print @array[ /\d+/g ], "\n";




John
 
J

John W. Krahn

Ilya said:
[A complimentary Cc of this posting was sent to
John W. Krahn
yl said:
Could anyone help explain this line of code?
$_->[/^(?>(.)?(.)+.*)(?!\1)(??{print(($1..$2)[15,4,17,11])})/]

I think it can be divided into 3 parts
1. (?>(.)?(.)+.*)
2. (?!\1)
3. (??{print(($1..$2)[15,4,17,11])})
and the 3rd part will print 'PERL'. But I got no idea how the variables
$1 and $2 was decided to form an array including 'A'..'Z' (though $2 is
not 'Z').
$_->[] autovivifies an array reference so $_ becomes a text string something
like ARRAY(0x12345678) which the regex operates on. ^(?>(.)?(.)+.*)(?!\1)
puts 'A' in $1 and 'R' in $2 giving the list 'A' .. 'R' from which the letters

Are you sure? Actually, $2 is ')'.

perl -wle "[1] =~ /^(?>(.)?(.)+.*)(?!\1)/ and print $2"
)

Looks like the .. operator (as opposed to ++ !!!) has alphanumeric
*output*, but arbitrary *input*: here 'A' .. ')' is the same as 'A' .. 'Z'.
Probably won't be so on EBCDIC.

That is weird. According to perlop: "If the left value is greater than the
right value then it returns the empty list.". And 'A' gt ')' (at least in
ASCII) so it should be an empty list.


John
 
T

Tad McClellan

yl said:
The $_->[/regex/] thing looks quite strange to me. I never thought a
regex can be placed in a bracket like this.


It is nothing more than a m// in a list context.

Is it a useful expression
that I can use in many situations


Yes, m// in a list context is often useful.
 
V

Vronans

John said:
Anno said:
John W. Krahn said:
yl wrote:
John W. Krahn 寫é“:

$_->[] autovivifies an array reference so $_ becomes a text
string something like ARRAY(0x12345678) which the regex operates
on. ^(?>(.)?(.)+.*)(?!\1)
The $_->[/regex/] thing looks quite strange to me. I never thought
a regex can be placed in a bracket like this. Is it a useful
expression that I can use in many situations or just for
demonstration of an advanced Perl skill?
In the example the regex wasn't used for its return value but for
the side effect of the print function.

An example of a useful use of a regex in an array slice:

my @array = 'a' .. 'z'; ^^^^^
$_ = ' 14 1 5 20 18 2 0 19 4 ';

print @a[ /\d+/g ], "\n";
^

Oops, sorry, I copied and pasted the wrong code, it should be:

my @array = 'a' .. 'z';

$_ = ' 14 1 5 20 18 2 0 19 4 ';

print @array[ /\d+/g ], "\n";

Even though it wasn't very difficult (for some of us) to mentally
translate it anyway :p
 
X

xhoster

yl said:
John W. Krahn =E5=AF=AB=E9=81=93=EF=BC=9A
$_->[] autovivifies an array reference so $_ becomes a text string
someth= ing
like ARRAY(0x12345678) which the regex operates on.
^(?>(.)?(.)+.*)(?!\1)

The $_->[/regex/] thing looks quite strange to me. I never thought a
regex can be placed in a bracket like this.

Any expression can go in the bracket. What is in the bracket is not
a bare regex, it is an expression, which in this case happens to consist of
a regex operator (m//). The operator is operating on a regex, but it is
not itself a regex.

Is it a useful expression
that I can use in many situations or just for demonstration of an
advanced Perl skill?

The particular code you posted would be better described as deranged than
advanced. It is intentionally obfuscated. I have never needed to use a
the result of a regex operator as an array index, but I can't gaurantee it
will never ever be useful for someone to do it.

Xho
 
P

Paul Lalli

Stan said:
Isn't it because the m// in list context (used inside [...]'s) gives you
a slice ?

m// in list context gives you a list. Nothing more. Specifically, it
is a list of all the captured sub matches (or the list of all global
matches if /g is used).

[ ], when applied to an existing array or list, gives you a slice.
Like this bit of code I wrtoe a while back, to make a simple ascii2hex
script:

my @a = \x01..\xFF;
$_ = '(1,2,3),(20,15,10)';
my %h = map{$_=>sprintf('0x%02X',ord($_))}@a[m!\d+!g];
print "$_ = $h{$_}\n" foreach (sort keys %h);

__OUTOUT__
1 = 0x31
2 = 0x32
3 = 0x33
a = 0x61
b = 0x62
c = 0x63

Odd, when I run that code, I get:
Bareword "xFF" not allowed while "strict subs" in use at ./clpm.pl line
4.
Bareword "x01" not allowed while "strict subs" in use at ./clpm.pl line
4.

After I correct that error (\x01 ==> 0x01, \xFF ==> 0xFF), I get:
11 = 0x31
16 = 0x31
2 = 0x32
21 = 0x32
3 = 0x33
4 = 0x34

Your m!\d+!g expression returned a list of all digit sequences from $_,
namely 1, 2, 3, 20, 15, 10. It then used these as the indices for a
slice of @a, which contained all the numbers from 1 to 255. Except
that the element of @a with index 1 is 2, index 2 is 3, etc. Arrays in
Perl are 0-indexed.

So the list that map{} was operating on was (2, 3, 4, 21, 16, 11). For
each element of this list, you created a key-value pair where the key
is the element itself, and the value is the ASCII value of the first
character of the element (1 for 11, 1 for 16, 2 for 2, 2 for 21, etc),
translated to hex.

I see no way for your code to produce the results you claimed you
received.

Paul Lalli
 
X

xhoster

Tad McClellan said:
yl said:
The $_->[/regex/] thing looks quite strange to me. I never thought a
regex can be placed in a bracket like this.

It is nothing more than a m// in a list context.

That seems like a scalar context.

$ perl -le 'sub foo {print wantarray ? "list":"scalar"}; $_->[foo()]'
scalar

Xho
 
P

Paul Lalli

Tad McClellan said:
yl said:
The $_->[/regex/] thing looks quite strange to me. I never thought a
regex can be placed in a bracket like this.

It is nothing more than a m// in a list context.

That seems like a scalar context.

$ perl -le 'sub foo {print wantarray ? "list":"scalar"}; $_->[foo()]'
scalar

It is. $_->[ ] is a scalar value, as you're grabbing a single value
from the array ref. If you grab a slice from the array ref, on the
other hand...

$ perl -le 'sub foo {print wantarray ? "list":"scalar"}; ${$_}[foo()]'
scalar
$ perl -le 'sub foo {print wantarray ? "list":"scalar"}; @{$_}[foo()]'
list

Paul Lalli
 

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,776
Messages
2,569,603
Members
45,188
Latest member
Crypto TaxSoftware

Latest Threads

Top