Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > How to use (??{code}) correctly in foreach loop?

Reply
Thread Tools

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

 
 
Peng Yu
Guest
Posts: n/a
 
      02-14-2011
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
 
Reply With Quote
 
 
 
 
Ilya Zakharevich
Guest
Posts: n/a
 
      02-14-2011
On 2011-02-14, Peng Yu <(E-Mail Removed)> 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
 
Reply With Quote
 
 
 
 
George Mpouras
Guest
Posts: n/a
 
      02-14-2011

"Peng Yu" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> 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";


 
Reply With Quote
 
George Mpouras
Guest
Posts: n/a
 
      02-14-2011
# 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";


 
Reply With Quote
 
Peng Yu
Guest
Posts: n/a
 
      02-14-2011
On Feb 14, 3:30*am, "George Mpouras"
<(E-Mail Removed)> 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?
 
Reply With Quote
 
George Mpouras
Guest
Posts: n/a
 
      02-14-2011
>>>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



 
Reply With Quote
 
Ilya Zakharevich
Guest
Posts: n/a
 
      02-15-2011
On 2011-02-14, Peng Yu <(E-Mail Removed)> 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
 
Reply With Quote
 
C.DeRykus
Guest
Posts: n/a
 
      02-15-2011
On Feb 13, 6:01*pm, Peng Yu <(E-Mail Removed)> 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


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
How to use macro correctly to get nice picture with Sony T1 satoshi Digital Photography 2 06-26-2005 04:44 AM
use collection of javaBean in forEach quickcur@yahoo.com Java 0 01-14-2005 05:53 AM
how to use logic:Empty within c:forEach PC Leung Java 0 06-30-2004 03:43 PM
Need help on how to use functions correctly Panic VHDL 0 08-25-2003 07:11 PM



Advertisments