Skip Menu |

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

Report information
The Basics
Id: 103905
Status: resolved
Priority: 0/
Queue: Regexp-Grammars

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

Bug Information
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