Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   How to use (??{code}) correctly in foreach loop? (http://www.velocityreviews.com/forums/t914672-how-to-use-code-correctly-in-foreach-loop.html)

Peng Yu 02-14-2011 02:01 AM

How to use (??{code}) correctly in foreach loop?
 
Hi,

I have the following code and output. I'm not sure why the code
doesn't search for 'abc' in the second string 'efgabcabcd'. Could you
anybody let me know what the problem is and how to fix it?

$ cat main.pl
#!/usr/bin/env perl

use strict;
use warnings;

my @strings=('abcdefgabc', 'efgabcabcd');
my $pattern='abc';

foreach my $s (@strings) {
my @offsets=();
{
use re 'eval';
$s =~ /(?=\Q$pattern\E)(??{push @offsets, $-[0]})/g;
}
print join('::', @offsets), "\n"
}
print "end\n";

$ ./main.pl
0::7

end

Ilya Zakharevich 02-14-2011 06:17 AM

Re: How to use (??{code}) correctly in foreach loop?
 
On 2011-02-14, Peng Yu <pengyu.ut@gmail.com> wrote:
> Hi,
>
> I have the following code and output. I'm not sure why the code
> doesn't search for 'abc' in the second string 'efgabcabcd'. Could you
> anybody let me know what the problem is and how to fix it?
>
> $ cat main.pl
> #!/usr/bin/env perl
>
> use strict;
> use warnings;
>
> my @strings=('abcdefgabc', 'efgabcabcd');
> my $pattern='abc';
>
> foreach my $s (@strings) {
> my @offsets=();
> {
> use re 'eval';
> $s =~ /(?=\Q$pattern\E)(??{push @offsets, $-[0]})/g;
> }
> print join('::', @offsets), "\n"
> }
> print "end\n";


I have no idea what do you want to achieve. Do you think it is a
scalar context //g, or a list content?

Anyway, I suspect a bug in scalar/list context //g applied to a
foreach-iterator. Did you try it without (??{}) ?

Ilya

George Mpouras 02-14-2011 09:28 AM

Re: How to use (??{code}) correctly in foreach loop?
 

"Peng Yu" <pengyu.ut@gmail.com> wrote in message
news:1831debc-88b0-4aee-bb5f-8156339a1350@i40g2000yqh.googlegroups.com...
> Hi,
>
> I have the following code and output. I'm not sure why the code
> doesn't search for 'abc' in the second string 'efgabcabcd'. Could you
> anybody let me know what the problem is and how to fix it?
>
> $ cat main.pl
> #!/usr/bin/env perl
>
> use strict;
> use warnings;
>
> my @strings=('abcdefgabc', 'efgabcabcd');
> my $pattern='abc';
>
> foreach my $s (@strings) {
> my @offsets=();
> {
> use re 'eval';
> $s =~ /(?=\Q$pattern\E)(??{push @offsets, $-[0]})/g;
> }
> print join('::', @offsets), "\n"
> }
> print "end\n";
>
> $ ./main.pl
> 0::7
>
> end




# Here is what you want
# somehow the (??{..@offsets...}) defines the arrray as local at the
namespace at first time
# and "my" undefine it or something like that !

use strict;
use warnings;

my @strings=('abcdefgabc', 'efgabcabcd');
my $pattern='abc';
my @offsets=();

use re 'eval';
foreach my $s (@strings)
{
$s =~ /(?=\Q$pattern\E)(??{push @offsets, $-[0]})/g;
print "Offsets of $s: @offsets\n"
}
no re;

print "end\n";



George Mpouras 02-14-2011 09:30 AM

Re: How to use (??{code}) correctly in foreach loop?
 
# sorry here is the correct one !

use strict;
use warnings;

my @strings=('abcdefgabc', 'efgabcabcd');
my $pattern='abc';
my @offsets=();

foreach my $s (@strings)
{
@offsets=();
{use re 'eval'; $s =~ /(?=\Q$pattern\E)(??{push @offsets, $-[0]})/g }
print "Offsets of $s: @offsets\n"
}

print "end\n";



Peng Yu 02-14-2011 01:45 PM

Re: How to use (??{code}) correctly in foreach loop?
 
On Feb 14, 3:30*am, "George Mpouras"
<nospam.gravital...@hotmail.com.nospam> wrote:
> # sorry here is the correct one !
>
> use strict;
> use warnings;
>
> my @strings=('abcdefgabc', 'efgabcabcd');
> my $pattern='abc';
> my @offsets=();
>
> foreach my $s (@strings)
> {
> @offsets=();
> {use re 'eval'; $s =~ /(?=\Q$pattern\E)(??{push @offsets, $-[0]})/g }
> print "Offsets of $s: @offsets\n"
>
> }
>
> print "end\n";


This works. Thank you!

Also, I don't quite understand why "my @offsets;" has to be moved out
of the loop.

I checked Programming Perl 3rd edition. There are thousands of "my" in
this book. Would you please help me understand why it is the case by
pointing me which page of Programming Perl or which perl document (and
what part of it) I should read?

George Mpouras 02-14-2011 02:13 PM

Re: How to use (??{code}) correctly in foreach loop?
 
>>>Also, I don't quite understand why "my @offsets;" has to be moved out of
>>>the loop.


There is nothing wrong with your code . It looks like a bug to me .
(??{...@offsets ...}) } somehow defines the array as global at first time ,
and "my" seems to overide this definition




Ilya Zakharevich 02-15-2011 06:51 PM

Re: How to use (??{code}) correctly in foreach loop?
 
On 2011-02-14, Peng Yu <pengyu.ut@gmail.com> wrote:
>> my @offsets=();
>>
>> foreach my $s (@strings)
>> {
>> @offsets=();
>> {use re 'eval'; $s =~ /(?=\Q$pattern\E)(??{push @offsets, $-[0]})/g }
>> print "Offsets of $s: @offsets\n"
>>
>> }


> This works. Thank you!
> Also, I don't quite understand why "my @offsets;" has to be moved out
> of the loop.


This one is new to me...

When I first implemented (??{}), I did not cover one case in
"dynamically create new chunk of compile tree" logic. This lead to
bugs when (??{}) accesses lexicals in recursive subroutines. (Not
hard to fix, but, apparently, nobody did it...)

Now you say that there is also a problem with accessing lexicals
defined inside a loop? Strange... Probably, the logic of the first
loop may be as in:

A lexical @array is created;

REx is compiled; the compile tree contains a reference to the @array;

On exit from the loop the garbage collector of lexicals checks the
refcount of @array; it is now 1 more than expected, so it thinks an
EXTERNAL reference to the array exists, and "renews" @array;

On following iterations "there is no visible need" to renew @array
and recompile the REx, so none of these steps happens. However, on
these iterations @array visible from Perl code and @array visible from
inside (??{}) are different containers.

Hope this helps,
Ilya

C.DeRykus 02-15-2011 08:15 PM

Re: How to use (??{code}) correctly in foreach loop?
 
On Feb 13, 6:01*pm, Peng Yu <pengyu...@gmail.com> wrote:
> Hi,
>
> I have the following code and output. I'm not sure why the code
> doesn't search for 'abc' in the second string 'efgabcabcd'. Could you
> anybody let me know what the problem is and how to fix it?
>
> $ cat main.pl
> #!/usr/bin/env perl
>
> use strict;
> use warnings;
>
> my @strings=('abcdefgabc', 'efgabcabcd');
> my $pattern='abc';
>
> foreach my $s (@strings) {
> * my @offsets=();
> * {
> * * use re 'eval';
> * * $s =~ /(?=\Q$pattern\E)(??{push @offsets, $-[0]})/g;
> * }
> * print join('::', @offsets), "\n"}
>
> print "end\n";
>
> $ ./main.pl
> 0::7
>
> end


Is there some reason you need to use (?{{...})
which is tagged 'experimental' ...

A simple alternative, eg:

my $regex = qr/abc/;
foreach my $s (@strings) {
push @offsets,$-[0] while $s =~ /$regex/g;
}

--
Charles DeRykus




All times are GMT. The time now is 09:46 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.