Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > variables crash inside (?{})

Reply
Thread Tools

variables crash inside (?{})

 
 
Jerome Abela
Guest
Posts: n/a
 
      05-02-2006
Hi there,

The following code comes directly from perlre(1), except it's inside a
sub:

animals();
animals();
sub animals {
my ($color, $animal);
$_ = "The brown fox jumps over the lazy dog";
/the (\S+)(?{ $color = $^N }) (\S+)(?{ $animal = $^N })/i;
print "color = $color, animal = $animal\n";
}

But its output is surprizing (at least with v5.8.5 and v5.8.7):

color = brown, animal = fox
color = , animal =

Everything works if I don't declare lexical variables, so it may be
related to some kind of scoping from inside the (?{}). But I can't find
any reasonable explanation for this behavior.

I need help from more knowledgeable people: how can I write more robust
code to be used from (?{}) expressions ?

Or, as an alternative, how can I store data matched inside nested
groups ? My real original code is more like:
m/special\((?:before(group)after(?{save it, using $^N}))*\)/
where the {save using $^N} part only works once because of the bug
above.


Jerome.

 
Reply With Quote
 
 
 
 
xhoster@gmail.com
Guest
Posts: n/a
 
      05-02-2006
"Jerome Abela" <(E-Mail Removed)> wrote:
> Hi there,
>
> The following code comes directly from perlre(1), except it's inside a
> sub:
>
> animals();
> animals();
> sub animals {
> my ($color, $animal);
> $_ = "The brown fox jumps over the lazy dog";
> /the (\S+)(?{ $color = $^N }) (\S+)(?{ $animal = $^N })/i;
> print "color = $color, animal = $animal\n";
> }
>
> But its output is surprizing (at least with v5.8.5 and v5.8.7):
>
> color = brown, animal = fox
> color = , animal =
>
> Everything works if I don't declare lexical variables, so it may be
> related to some kind of scoping from inside the (?{}). But I can't find
> any reasonable explanation for this behavior.



The regex gloms onto the $color and $animal which are in scope the first
time the regex is encountered, and doesn't update them. The second time
animals is called, a different $color and $animal are created, but the
regex is still using the old ones.

It appears to be just like as if you did:

animals();
animals();
sub animals {
my ($color, $animal);
sub foo {
$color="brown";
$animal="fox";
};
foo();
print "color = $color, animal = $animal\n";
}

Only this generates a 'Variable "$color" will not stay shared' warning
while the regex does not generate warnings.


> I need help from more knowledgeable people: how can I write more robust
> code to be used from (?{}) expressions ?


Considering the "highly experimental" disclaimer, I would suggest you can't
write robust code to be used thus. Ignoring that, use a package variable.

>
> Or, as an alternative, how can I store data matched inside nested
> groups ?


I've never had problems doing that with plain old regular expressions.

> My real original code is more like:
> m/special\((?:before(group)after(?{save it, using $^N}))*\)/
> where the {save using $^N} part only works once because of the bug
> above.


How about something like:

my ($thing) = m/special\(((?:beforegroupafter)*)\)/ or die;
my (@data) = $thing=~/before(group)after/g;

Xho

--
-------------------- http://NewsReader.Com/ --------------------
Usenet Newsgroup Service $9.95/Month 30GB
 
Reply With Quote
 
 
 
 
Brian McCauley
Guest
Posts: n/a
 
      05-02-2006

Jerome Abela wrote:
> Hi there,
>
> The following code comes directly from perlre(1), except it's inside a
> sub:
>
> animals();
> animals();
> sub animals {
> my ($color, $animal);
> $_ = "The brown fox jumps over the lazy dog";
> /the (\S+)(?{ $color = $^N }) (\S+)(?{ $animal = $^N })/i;
> print "color = $color, animal = $animal\n";
> }
>
> But its output is surprizing (at least with v5.8.5 and v5.8.7):
>
> color = brown, animal = fox
> color = , animal =
>
> Everything works if I don't declare lexical variables, so it may be
> related to some kind of scoping from inside the (?{}). But I can't find
> any reasonable explanation for this behavior.


There is no reasonable explaination for why (?{}) doesn't play nicely
with lexical variables. There's an unreasonable one analagous to the
mechanism that results in the the "will not remain shared" warning.

This is a know problem but (?{}) is still considered experimental isn't
it?

> I need help from more knowledgeable people: how can I write more robust
> code to be used from (?{}) expressions ?


Until further notice use only package variables inside (?{}).

Simply change

my ($color, $animal);

to

local our ($color, $animal);

 
Reply With Quote
 
Jerome Abela
Guest
Posts: n/a
 
      05-03-2006
Thanks a lot, Xho and Brian !

Now, I have a nice explanation of what happens (the regex creates a
closure on the lexical variables when executed for the first time), and
I have the solution, which consist in using "our", so that both the
closure and my local variables refer to the same thing.

Thank you to both of you !

> How about something like:
> my ($thing) = m/special\(((?:beforegroupafter)*)\)/ or die;
> my (@data) = $thing=~/before(group)after/g;


"before", "group", and "after" are complex regexps, so it hurts to
execute them twice.


Jerome.

 
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
program that ain't crash inside debugger console kid C++ 6 03-31-2011 06:21 PM
Put variables into member variables or function variables? tjumail@gmail.com C++ 9 03-23-2008 04:03 PM
Problem with inside to inside traffic after upgrading PIX 515 Cisco 5 06-15-2004 06:34 AM
Dynamic temp. datagrid col.gen. -Session access inside a class inside a UserCtrl Andy Eshtry ASP .Net 0 03-01-2004 11:48 PM
CRASH - DirectX End-User runtime - CRASH - What to to ? reply@newsgroup.please Computer Support 1 01-05-2004 02:55 PM



Advertisments