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

sometimes we have some big expressions that get some members of an object like tree->ancestor->son->sibbling->...->bla->bla its annoying to always have to do like

if( ( tree->ancestor->son->sibbling->...->bla->bla eq "john") or ( tree->ancestor->son->sibbling->...->bla->bla eq "Mary") )
is there a way of expressing something like:
if ( expression is_in (val1,val2,val3) )
it would be very helpful

Replies are listed 'Best First'.
Re: a natural way of expressing things
by FunkyMonk (Bishop) on Jul 08, 2007 at 00:22 UTC
    Have a look at any in List::MoreUtils:

    if ( any { $expression eq $_ } $val1, $val2, $val3 ) { #blah, blah, blah }

      Are there are any advantages in using any from List::MoreUtils over using grep?

      if ( grep { $expression eq $_ } $val1, $val2, $val3 ) { ... }

      Just wondering as I'm not really familiar with that module.

      Cheers,

      JohnGG

          scalar context list context
        grep looks at the entire list and returns the number of times the expression was true returns the list of things that matched
        any only looks at as much of the list as it needs to. ie it will stop after the first true condition.

        I've never tried a table on PM before. It looks OK(ish) here. Please /msg me if it's a disaster on other platforms.

        update: I was using <table border-width=1> instead of border=1. Thanks to holli for noticing.

Re: a natural way of expressing things
by Limbic~Region (Chancellor) on Jul 08, 2007 at 00:16 UTC
    spx2,
    Typically, you would store the result of the long expression in a variable with a shorter name if you need to re-use the results in a number of later statements. That really isn't needed here but I have included it as it comes in handy.
    my $name = $tree->ancestor->son->sibbling; if ($name =~ /john|jacob|jingle|heimer|smitz/) { # ... }
    There are a number of different ways to check to see if the value is in a list. I provided a regex alternation but there is also grep or, for the truly bizarre, Quantum::Superpositions. Note: the alternation regex can be constructed using join.

    Minor update regarding the reason why you store the result in a shorter variable.

    Cheers - L~R

      Alternatively a one-shot for loop can be used:

      for my $name ( $tree->ancestor->son->sibbling ) { if ( $name ... ) { # ... } # ... }
      Differences:

    • $name is scoped within the for block
    • $name is an alias of the original, not a copy

      Anno

Re: a natural way of expressing things
by GrandFather (Saint) on Jul 08, 2007 at 00:22 UTC

    Knowing the bigger picture would help here because the "best" answer depends a lot on context. The general answer to "is this thing an element of that set" is to use a hash:

    my %hash; @hash{val1, val2, val3} = undef; if (exists $hash{$test}) { }

    But if you want "do something if this thing is an element of that set" then you can use a hash to dispatch:

    my %hash = (val1 => \&task1, val2 => \&task2, val3 => \&task3); if (exists $hash{$test}) { $hash{$test}->(); }

    DWIM is Perl's answer to Gödel