Beefy Boxes and Bandwidth Generously Provided by pair Networks Cowboy Neal with Hat
Welcome to the Monastery
 
PerlMonks  

Re^2: Extracting the number of repetitions from a regex

by pat_mc (Pilgrim)
on Dec 18, 2008 at 20:40 UTC ( #731384=note: print w/ replies, xml ) Need Help??


in reply to Re: Extracting the number of repetitions from a regex
in thread Extracting the number of repetitions from a regex

Cool stuff, BrowserUk!

This really does the trick. Since I am not really clear on the difference between 'Lexicals' and 'Globals' - could you please briefly expand on how the change from declaring the variables with my to our affects this scenario? I expected the scope of a variable definition to be that of the block is was defined in ... hence my confusion as to why the use of globals would make any difference here.

Thanks again - Pat


Comment on Re^2: Extracting the number of repetitions from a regex
Select or Download Code
Re^3: Extracting the number of repetitions from a regex
by ikegami (Pope) on Dec 18, 2008 at 21:03 UTC

    could you please briefly expand on how the change from declaring the variables with my to our affects this scenario?

    Briefly? Code blocks in regexp patterns capture lexical variabless when they are compiled, just like anonymous subs. Package variables aren't captured. In case that didn't do the trick, the longer answer follows.

    Code blocks in regexps are anonymous subs.

    sub f { my ($x) = @_; '' =~ /(?{ print "$x\n" })/; } f(4); # 4 f(5); # 4!!
    effectively does
    sub f { my ($x) = @_; $block ||= sub { print "$x\n" }; $block->(); } f(4); # 4 f(5); # 4!!

    The $x from the first pass is captured when the sub is compiled. It's a very powerful feature which allows the simplification of many problems. For example,

    BEGIN { package Prefixer; sub new { my ($class, $prefix) = @_; return bless({ prefix => $prefix }, $class); } sub prefix { my ($self) = @_; return join '', $self->{prefix}, @_; } } my $a_prefixer = Prefixer->new('a'); my $b_prefixer = Prefixer->new('b'); print("$_\n") for $a_prefixer->prefix('1'), # a1 $a_prefixer->prefix('2'), # a2 $b_prefixer->prefix('3'), # b3 $b_prefixer->prefix('4'); # b4

    can be simplified to

    sub make_prefixer { my ($prefix) = @_; return sub { return join '', $prefix, @_ }; } my $a_prefixer = make_prefixer('a'); my $b_prefixer = make_prefixer('b'); print("$_\n") for $a_prefixer->('1'), # a1 $a_prefixer->('2'), # a2 $b_prefixer->('3'), # b3 $b_prefixer->('4'); # b4

    However, subs only capture lexical variables, not package variables. By using package variables, the problem goes away.

    sub f { local our ($x) = @_; $block ||= sub { print "$x\n" }; $block->(); } f(4); # 4 f(5); # 5
    sub f { local our ($x) = @_; '' =~ /(?{ print "$x\n" })/; } f(4); # 4 f(5); # 5
      Code blocks in regexps are anonymous subs.
      Wow - ikegami ...

      It's all making sense to me now. Thanks for the enlightenment! If calling a code block in a regex is effectively the same as calling a subroutine then I understand why the scope of the my variable in my initial code snipped is not wide enough!

      Your wisdom and taking the time to share it are much appreciated.

      Cheers - Pat

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://731384]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (12)
As of 2013-05-24 15:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best material for plates (tableware) is:









    Results (509 votes), past polls