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

Hello,

Is there a way to do something like:

$monitoredActions = "ADD|REMOVE|DELETE"; if ($action =~ /$monitoredActions/) { // do something }
I want to define what actions will be monitored from what a user inputs using GetOpt::Long. So sometimes they might set $monitoredActions = "ADD", and another time they might enter more than one thing to monitor (e.g., "ADD|DELETE"). What is best way to handle this without writing a bunch of if..then.else?

David

Edit by tye, preserve formatting

Replies are listed 'Best First'.
Re: build regular expression from scalar?
by dragonchild (Archbishop) on Nov 26, 2003 at 19:44 UTC
    Have you tried your sample code in a test script? I suspect you'll be pleasantly surprised.

    (Hint: do not use the /o option for regexes when doing this. You'll be unpleasantly surprised.)

    ------
    We are the carpenters and bricklayers of the Information Age.

    The idea is a little like C++ templates, except not quite so brain-meltingly complicated. -- TheDamian, Exegesis 6

    ... strings and arrays will suffice. As they are easily available as native data types in any sane language, ... - blokhead, speaking on evolutionary algorithms

    Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

Re: build regular expression from scalar?
by jeffa (Bishop) on Nov 26, 2003 at 22:21 UTC
    I would prefer to use such a program like so:
    ./monitor.pl -add -remove
    but since that would surely involve an if-else of some kind, how about a usage such as this:
    ./monitor.pl -action ADD -action REMOVE
    instead? Especially since Getopt::Long will stuff all -action arguments into an array for you. If this is acceptable for you, then feel free to mangle the following skeleton. Since you wanted to use a regular expression, how about we bring Tie::Hash::Regex along for the ride. Hope you like Pod::Usage as well. ;)

    Oh, buy the way ... i really tried to avoid any if's or unless's by replacing them with and's and or's. I don't normally do that, as it's not always apparent what's really going on, but i thought you might enjoy Another Way To Do It. ;)

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Re: build regular expression from scalar?
by Roger (Parson) on Nov 26, 2003 at 22:41 UTC
    What's wrong with if's? Personally I think they make your program much easier to read and understand...
    #!/usr/local/bin/perl -w use Getopt::Long; use Pod::Usage; use strict; # Parse command line arguments and assign corresponding variables GetOptions ( 'a|add' => \( my $ADD = undef ), 'r|remove' => \( my $REMOVE = undef ), 'd|delete' => \( my $DELETE = undef ), ); unless ( defined $ADD or defined $REMOVE or defined $DELETE ) { pod2usage( -exitval => 1, -output => \*STDERR ); } if ($ADD) { ... } if ($REMOVE) { ... } if ($DELETE) { ... }
    And you run the script with -
    # the short form script.pl -a -r -d script.pl -a -d ... # the long form script.pl --add --remove --delete script.pl --delete ...
    Update: Here's a different approach - provide a list of commands to monitor on the commandline, separated by commas.

    #!/usr/local/bin/perl -w use Getopt::Long; use Data::Dumper; use strict; # Parse command line arguments and assign corresponding variables GetOptions ( 'm|monitor=s' => \( my $MON = undef ), ); unless ( defined $MON ) { print <<EOF Usage: $0 <-m|--monitor [ADD][,REMOVE][,DELETE]> Example: $0 -m ADD,DELETE $0 -m remove,delete Note: No space between comma and commands EOF ; exit(1); } my @options = map { uc } (split /,/, $MON); # verify input commands my @allowed_commands = qw/ ADD REMOVE DELETE /; foreach my $opt (@options) { die "Unknown command $opt" if ! scalar grep $opt eq $_, @allowed_commands; } my $monitor_commands = join '|', @options; # DEMO - give it a little test in action monitor... # @actions simulates a sequence of commands my @actions = qw/ ADD ADD REMOVE ADD DELETE FREE /; foreach my $action (@actions) { if ($action =~ /($monitor_commands)/) { print "Command [$action] is monitored\n"; } else { print "Command [$action] is NOT monitored\n"; } }
    And the output for script.pl -m add,delete is -
    Command [ADD] is monitored Command [ADD] is monitored Command [REMOVE] is NOT monitored Command [ADD] is monitored Command [DELETE] is monitored Command [FREE] is NOT monitored
Re: build regular expression from scalar?
by holo (Monk) on Nov 26, 2003 at 21:27 UTC

    You could use a hash of coderefs:

    my %actions = ( ADD = \&add, DELETE = \&delete, REMOVE = \&remove, ); # ... if($action =~ /$monitoredActions/) { $_ = uc($action); if(exists $actions{$_}) { $actions{$_}->(); } else { # undefined action. die/warn whatever } } sub add { ... } sub delete { ... } sub remove { ... }

    Update: had misunderstood question.

Re: build regular expression from scalar?
by davido (Cardinal) on Nov 27, 2003 at 05:01 UTC
    You could even do something like this:

    # Figure out what actions the user wants to monitor. my $monitored_actions = join "|", @ARGV; # Create a monitoring RE that can be used again and again # without re-compiling it. my $monitor = qr/$monitored_actions/; { # Decide what action to take. my $action = ('ADD', 'REMOVE', 'DELETE', 'QUIT')[rand(3)]; # And here we monitor it. $action =~ /$monitor/ && do { print $action, "\n"; }; redo unless $action eq 'QUIT'; }

    Then run it from the command line like this:

    ./mytest ADD REMOVE

    TI(always)MTOWTDI


    Dave


    "If I had my life to live over again, I'd be a plumber." -- Albert Einstein
Re: build regular expression from scalar?
by Anonymous Monk on Nov 26, 2003 at 23:23 UTC

    Here you go, sans if/else:

    $actions = "ADD|JUNK|DEL"; sub{(${{ ADD => sub{print "Adding\n"}, DEL => sub{print "Deleting\n"}, REM => sub{print "Removing\n"},}}{$_} or sub{print "I'm Sorry Dave. I can't do <$_>.\n"} )->() }->() for split/\|/,$actions;