This queue is for tickets about the Regexp-Grammars CPAN distribution.

Report information
The Basics
Id:
103905
Status:
resolved
Priority:
Low/Low

People
Owner:
Nobody in particular
Requestors:
DAVEWOOD [...] cpan.org
Cc:
AdminCc:

BugTracker
Severity:
(no value)
Broken in:
(no value)
Fixed in:
(no value)



Subject: Regexp::Grammars does not work in Moose::Role
Error msg: Global symbol "%keywords" requires explicit package name at (eval 172) line 32. #!/usr/bin/env perl use 5.018; use warnings; package ReRole; use Moose::Role; use Regexp::Grammars; use Data::Dumper; sub doit { my %keywords = (foo => 1, bar => 1); my $parser = qr/ ^<keyword>$ <rule: keyword> <%keywords> /xms; if ( "foo" =~ $parser ) { warn Dumper(\%/); } } package Re1; use Moose; with 'ReRole'; doit(); if you run the Regexp::Grammars code standalone it does not complain about the %keywords hash.
This works: #!/usr/bin/env perl use 5.018; use warnings; package ReRole; use Moose::Role; use Regexp::Grammars; use Data::Dumper; my %keywords = (foo => 1, bar => 1); sub doit { my $parser = qr/ ^<keyword>$ <rule: keyword> <%keywords> /xms; if ( "foo" =~ $parser ) { warn Dumper(\%/); } } package Re1; use Moose; with 'ReRole'; doit(); This does *not* work: #!/usr/bin/env perl use 5.018; use warnings; use Regexp::Grammars; use Data::Dumper; sub doit { my %keywords = (foo => 1, bar => 1); my $parser = qr/ ^<keyword>$ <rule: keyword> <%keywords> /xms; if ( "foo" =~ $parser ) { warn Dumper(\%/); } } doit(); This works: #!/usr/bin/env perl use 5.018; use warnings; use Regexp::Grammars; use Data::Dumper; my %keywords = (foo => 1, bar => 1); sub doit { my $parser = qr/ ^<keyword>$ <rule: keyword> <%keywords> /xms; if ( "foo" =~ $parser ) { warn Dumper(\%/); } } doit(); Looks like the R::G compiler can't see the lexical variable inside the sub, but it can see it outside of it. Maybe literals are compiled before pads are built? This works: #!/usr/bin/env perl use 5.018; use warnings; use Regexp::Grammars; use Data::Dumper; sub doit { my %keywords = (foo => 1, bar => 1); my $parser = eval q{qr/ ^<keyword>$ <rule: keyword> <%keywords> /xms}; if ( "foo" =~ $parser ) { warn Dumper(\%/); } } doit();
Subject: Re: [rt.cpan.org #103905] Regexp::Grammars does not work in Moose::Role
Date: Fri, 24 Apr 2015 07:47:50 +1000
To: bug-Regexp-Grammars@rt.cpan.org
From: Damian Conway <damian@conway.org>
Thank-you both for the report and the follow-up explorations.

I do not believe there is any solution to this issue, except as DAKKAR
has indicate

I will document the limitation, and the suggested workaround, in the next release.

Damian
Subject: Re: [rt.cpan.org #103905] Regexp::Grammars does not work in Moose::Role
Date: Fri, 24 Apr 2015 08:03:08 +1000
To: bug-Regexp-Grammars@rt.cpan.org
From: Damian Conway <damian@conway.org>
BTW, this only occurs for regexes that contain no variable interpolations.
Another way to fix the problem is:

    sub doit {
        my %keywords = (foo => 1, bar => 1);
        my $runtime = '';
        my $parser = qr/ $runtime     # <----- Defers regex compilation to runtime
                            ^<keyword>$
                            <rule: keyword>
                            <%keywords>
            /xms;

        if ( "foo" =~ $parser ) {
            warn Dumper(\%/);
        }
    }

Or even:

    sub doit {
        my %keywords = (foo => 1, bar => 1);
        my $parser = qr/ ${\""}    # <---- Ditto, only scarier and ugler :-)
                            ^<keyword>$
                            <rule: keyword>
                            <%keywords>
            /xms;

        if ( "foo" =~ $parser ) {
            warn Dumper(\%/);
        }
    }

Damian



This service runs on Request Tracker, is sponsored by The Perl Foundation, and maintained by Best Practical Solutions.

Please report any issues with rt.cpan.org to rt-cpan-admin@bestpractical.com.