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

Dear brothers,
Could you advise me any ideas may use object method as criteria in the regexp and if yes - how?
# Some package; package C; sub flag { return 1; } # Some script #!/usr/bin/perl -w if(m{C->flag}x) { print "Ok\n" } else { print "Not good\n" }
TIA.
      
--------------------------------
SV* sv_bless(SV* sv, HV* stash);

Replies are listed 'Best First'.
Re: Regexp and object's methods.
by Tomte (Priest) on May 02, 2003 at 10:40 UTC

    You may use (?{ code }), with the perlre-warning in mind:
    WARNING: This extended regular expression fea­ ture is considered highly experimental, and may be changed or deleted without notice.

    An example:

    #!/usr/bin/perl package Test; sub test { return 'test_1'; } package main; if ( 'test_1' =~ m/(?{ Test::test() })/) { print "ok\n"; } else { print "not ok\n"; } __END__ ok

    regards,
    tomte


    Hlade's Law:

    If you have a difficult task, give it to a lazy person --
    they will find an easier way to do it.

Re: Regexp and object's methods.
by broquaint (Abbot) on May 02, 2003 at 11:10 UTC
    There's always the ol' 'scalar ref/deref in a string' trick e.g
    sub word { '( \w+ )' } print "Hello World" =~ /${\ main->word }/x; __output__ Hello

    HTH

    _________
    broquaint

Re: Regexp and object's methods.
by Tanalis (Curate) on May 02, 2003 at 10:12 UTC
    Hi,

    You could always assign the return value of the object method to a variable, then attempt to match that variable:

    my $value = C->flag(); if (m/$value/} { print "OK" } else { print "Not OK" }
    There may well be a better way, but that's the first that comes to mind.

    Hope that helps,
    -- Foxcub
    A friend is someone who can see straight through you, yet still enjoy the view. (Anon)

Re: Regexp and object's methods.
by Jasper (Chaplain) on May 02, 2003 at 11:12 UTC
    If the return from the method call is the only thing you want to test against, just match against that:
    $_ =~ C->flag();
    If you need to have specific matches within the match (I mean $1, $2 or whatever), you'd have to construct the regex in the method.
    sub flag { return '(.)foo(\\d+)bar' }
    $1 and $2 would be available.
    You can't pad either side of the match by surrounding it with // and adding things in, because that just wouldn't work.

    Jasper
Re: Regexp and object's methods.
by JamesNC (Chaplain) on May 02, 2003 at 13:35 UTC
    #--- complex.pm package complex; use strict; sub whatis{ my $self = shift; my $input = shift; my %data = ( ip_address => \qr/\d+\.\d+\.\d+\.\d+/, phone => \qr/^\d{3}[-]\d{3}[-]\d{4}$/, ); foreach(keys %data){ return $data{$_} if /$input/; } return 0; } 1; #--- test.pl #!/perl/bin/perl use complex; use strict; my @list1 = qw ( 704-123-4569 115.43.2.123 112.32.24.2 ); push @list1, "312-231-2312 (ext. 23)"; my @list2 = qw ( ip_address phone ); foreach (@list1){ foreach my $x (@list2){ if ( /${complex->whatis($x)}/ ){ print "$_ is an $x\n"; } } if ( /${complex->whatis('phone')}*\s+\(ext\. (\d+)\)/ ){ print "$_ is an phone with ext $1 \n"; } }
    Don't know if this helps... return a ref to your objects variable? then de-ref it in your regex and append any additonal expressions? (In this example, I use qr to in the hash, and pass a ref back... I think I can see why you would do this... interesting..)

    James :)
Re: Regexp and object's methods.
by nite_man (Deacon) on May 02, 2003 at 11:55 UTC
    Many thanks, brothers, for your suggestion.
    I'm sorry for my not clear question. I'd like to define it more exactly.
    I have a package with defined constants:
    package C; my $consts = { CONST1 => 1, CONST2 => 2, CONST3 => 3, CONST4 => 4, . . . }; use overload '``' => sub { return $const_values{shift} } ; # All constants can be accessed as by using AUTOLOAD sub AUTOLOAD { no strict 'refs', 'subs'; if ($AUTOLOAD =~ /.*::([A-Z]\w+)$/) { my $const_name = $1; *{$AUTOLOAD} = sub {return $const_values{$const_name}}; return $const_values{$const_name}; } return undef; } 1;
    In may script I have some choises:
    if($status == C->CONST1) { print "1" } elsif($status =~ /(2|3)/ { print "2 or 3" } else { print 'Something' }
    I'd like to use my constants intead of numbers:
    if($status == C->CONST1) { print "1" } elsif($status =~ /(C->CONST2|C->CONST3)/ { print "2 or 3" } else { print 'Something' }
    but it doesn't work. Of course, I know that I can write like this:
    $status == C->CONST3 or $status == C->CONST3
    But I wouldn't like to do it.
    Any suggestion will be helpful.
          
    --------------------------------
    SV* sv_bless(SV* sv, HV* stash);
    

      As far as I read perlre, (?{}) is the only way to get code directly into a regexp.

      so your wanted code must look like:

      if ($status == C->CONST1) { print "1" } elsif ($status =~ /(?{ C->CONST2 })|(?{ C->CONST3 })/) { print "2 or 3" ; } else { print 'Something'; }

      I don't see, why you don't want to use some of the more readable solutions suggested by the other monks, espacially a sub that assembles the regexp for you seems a good way to me, though...
      maybe that I really don't understand what you want to do...

      regards,
      tomte


      Hlade's Law:

      If you have a difficult task, give it to a lazy person --
      they will find an easier way to do it.

Re: Regexp and object's methods.
by nite_man (Deacon) on Feb 18, 2004 at 15:40 UTC

    Many thanks brothers, especially broquaint - excellent trick!!! ++++++++++++++++++++++++

    ~ Schiller