lowone has asked for the wisdom of the Perl Monks concerning the following question:

I want to build a regex object that I can pass to a general purpose subroutine that will bind dynamically to a "my" variable inside the routine.
Here's an example of what I'm trying to do.
/usr/bin/perl -w use strict; my $client = 123; # default value my $regx = qr/$client/; check_logs($regx); sub check_logs { my $regx = shift(@_); my @clients = qw(abc, def, hij); foreach my $client (@clients) { print($regx, "\n"); } # I want the $regex to bind to the $clie +nt variable inside the sub. }

In my real world problem my regex has other literals
before and after the $client variable that I will be
passing to my subroutine. I'm trying to avoid having a
$pre_regex and post_regex surrounding my $client
variable that I would have to pass into my subroutine.
I want to write a general purpose routine to handle log
files with different namings standards.

lowone (newbie)

Janitored by Arunbear - added code tags

Replies are listed 'Best First'.
Re: dynamic regex variable
by ikegami (Patriarch) on Oct 02, 2004 at 02:45 UTC

    How about:

    sub check_logs { my $regx_maker = shift(@_); my @clients = qw(abc def hij); foreach my $client (@clients) { my $regx = &$regx_maker($client); print($regx, "\n"); } } foreach my $regx_maker ( sub { my $client = shift; qr/pre-${client}-post/ }, sub { my $client = shift; qr/foo-${client}-bar/ }, ) { check_logs($regx_maker); } __END__ output ====== (?-xism:pre-abc-post) (?-xism:pre-def-post) (?-xism:pre-hij-post) (?-xism:foo-abc-bar) (?-xism:foo-def-bar) (?-xism:foo-hij-bar)

      Here's an alternative that matches your specs without using eval:

      sub check_logs { my $regx_template = shift(@_); my @clients = qw(abc def hij); foreach my $client (@clients) { my $regx = $regx_template; $regx =~ s/\\\$(?:client\b|{client})/$client/g; print($regx, "\n"); } } foreach my $regx_template ( qr/pre-\$client-post/, qr/foo-\$client-bar/, qr/moo\${client}moo/, ) { check_logs($regx_template); } __END__ output ====== (?-xism:pre-abc-post) (?-xism:pre-def-post) (?-xism:pre-hij-post) (?-xism:foo-abc-bar) (?-xism:foo-def-bar) (?-xism:foo-hij-bar) (?-xism:mooabcmoo) (?-xism:moodefmoo) (?-xism:moohijmoo)
Re: dynamic regex variable
by TGI (Parson) on Oct 02, 2004 at 02:51 UTC
    Make an object for each $pre and $post set of regex bits.
    package LogMatch; sub new { my $class = shift; my %args = @_; my $self = {}; $self->{pre} = $args{pre} || 'PREdefault'; $self->{post} = $args{post} || 'POSTdefault'; $self->{term} = $args{term} || 'TERMdefault'; bless $self, $class; } sub search { my $self = shift; my $term = shift; $term = $self->{term} unless defined $term; return qr/$self->{pre}$term$self->{post}/; } 1; package main; my $s1 = LogMatch->new(pre=>'\d\d\d\d',post=>',',term=>'foo'); my $s2 = LogMatch->new; my @clients = qw( foo bar baz hazmat coz meat ); foreach my $client (@clients) { my $regex1 = $s1->search($client); my $regex2 = $s2->search($client); print "$regex1\t\t$regex2\n"; }


    TGI says moo

Re: dynamic regex variable
by educated_foo (Vicar) on Oct 02, 2004 at 03:20 UTC
    This sounds like a good place for "eval":
    sub foo { my $client = 'a.b'; my $re = eval shift; grep /$re/, @_; } foo(q{qr|<$client>|}, '<a.b>', '<asb>', '<abs>'); # ==> ('<a.b>', '<asb>')
      eval would be too much