Re: Lexical variables in (?{...}) regexp constructs



On Tue, 16 Jun 2009 12:03:48 -0700 (PDT), Ala <ala.netstuff@xxxxxxxxx> wrote:

On Jun 15, 5:00 pm, s...@xxxxxxxxxxxxxxx wrote:

Probably the key phrase is "the Perl code contained in these blocks";
Imbedding code inside of a regular expression really has limited use
unless used in conjunction with a conditional or to immediatly store
the value of the last capture group.

Thanks for the reply. I realize my post wasn't very informative, and
that I'm probably playing with fire :)
Storing the last captured match is exactly what I'm using this
construct for. The basic idea is that I created a module to help parse
some non-trivial file format. The constructor of this module allows
the user to specify which parts of each record to capture and into
which variable to put it. It returns a compiled regexp that the user
can use when parsing. Something like this contrived example:

use R;
my ($name, $x, $y);
my $rgx = R->new(-capture => {
name => \$name,
locx => \$x,
locy => \$y,
});

#... later on .. use $rgx ..
while (<$fh>) {
if (/$rgx/) {
print "$name is at ($x, $y).\n";
}
}

I used this module as part of a larger module, let's call it M, that
parses the whole file and defines some other methods to manipulate the
data.
For the most part, this works perfectly well. Weird things start to
happen, seemingly in a random fashion, when I instantiate module M
multiple times in a loop.

I guess I shouldn't be relying on experimental features, but since the
docs mentioned a work-around, I was curious.

Thanks,
--Ala

As far as I know, lexicals scoped within the block that initiates the
regex, should be ok, be it a reference or not (haven't tried it but assume its ok).
pseudo - example:
SCOPE:
{
my ($name, $x, $y);
my ($ref_name, $ref_x, $ref_y) = (\$name, \$x, \$y);

my $rgx = qr/([a-z,A-Z]+)(?{$$name = $^N})(\d\d)(?{$$x = $^N}),(\d\d)(?{$$y = $^N})/;
while (<$fh>) {
if (/$rgx/) {
print "$name is at ($x, $y).\n";
}
}
};

If what you say is true, this is the case:

Package M;
use R;
my ($name, $x, $y);
my $rgx = R->new();
.... more code
if (/$rgx/) { }
1;

As a side, the R->new() is being used as just a class function call.
It does not bless() anything it appears since it is returning a string scalar.

Then somewhere else, you create multiple instances of M
(or just call M methods) in in a loop.

The my ($name, $x, $y) appear to be file scoped variables.
In the context I wrote, there is only one instance of ($name,$x,$y) no
matter how many instances of M you create (class scoped?).

If you had a method in M that creates many $rgx's, it would have to store
those qr// in an object based (M) blessed referent (hash or array) for them
and thereby thier references ($name,$x,$y) to persist.

Usually this involves fleshing out either R or M with references to unique
lexicals.

So that this is the case (usually):

while (<$fh>) {
if (/$obj->$rgx/) {
print "$obj->$name is at ($obj->$x, $obj->$y).\n";
}
}

More than likely you would need accessors.

Hope this helps.
-sln

.



Relevant Pages

  • Re: Teach me how to fish, regexp
    ... >> mechanisms I've found in some perl references. ... Parens capture the matched stuff. ... Apparently only specially-marked parens do NOT capture stuff, ... > perlre documentation for a full explanation. ...
    (comp.lang.perl.misc)
  • Re: Request TimeOut Question...
    ... If your users are getting that crude error page in the first place, ... you aren't using custom error pages. ... > - There are no references to the executing page on the error page??? ... How do I capture that error? ...
    (microsoft.public.dotnet.framework.aspnet)
  • Re: Paul talks about Linda
    ... references IS an awfully great shot: ... How'd she capture them all in those positions (including the dog) at ...
    (rec.music.beatles)
  • Re: Paul talks about Linda
    ... I didn't find his article all that moving, but one of the photos he ... references IS an awfully great shot: ... How'd she capture them all in those positions at ...
    (rec.music.beatles)