Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<h2>UPDATE:</h2> <blockquote> <p><a href="https://metacpan.org/pod/release/RJBS/perl-5.18.0/pod/perldelta.pod#The-smartmatch-family-of-features-are-now-experimental" rel="noreferrer">The smartmatch family of features are now experimental</a></p> <p>Smart match, added in v5.10.0 and significantly revised in v5.10.1, has been a regular point of complaint. Although there are a number of ways in which it is useful, it has also proven problematic and confusing for both users and implementors of Perl. There have been a number of proposals on how to best address the problem. It is clear that smartmatch is almost certainly either going to change or go away in the future. Relying on its current behavior is not recommended.</p> <p>Warnings will now be issued when the parser sees ~~, given, or when. </p> </blockquote> <hr> <hr> <hr> <h2>If you can get away with requiring Perl v5.10, then you can use any of the following examples.</h2> <ul> <li><p>The <a href="http://perldoc.perl.org/perlsyn.html#Smart-matching-in-detail" rel="noreferrer">smart match <code>~~</code></a> operator.</p> <pre><code>if( $element ~~ @list ){ ... } if( $element ~~ [ 1, 2, 3 ] ){ ... } </code></pre></li> <li><p>You could also use the <a href="http://perldoc.perl.org/perlsyn.html#Switch-statements" rel="noreferrer" title="Perl 5 &amp; 6 version of switch/case"><code>given</code>/<code>when</code></a> construct. Which uses the smart match functionality internally.</p> <pre><code>given( $element ){ when( @list ){ ... } } </code></pre></li> <li><p>You can also use a <code>for</code> loop as a "topicalizer" ( meaning it sets <code>$_</code> ).</p> <pre><code>for( @elements ){ when( @list ){ ... } } </code></pre></li> </ul> <p>One thing that will come out in Perl 5.12 is the ability to use the post-fix version of <code>when</code>. Which makes it even more like <code>if</code> and <code>unless</code>.</p> <pre><code>given( $element ){ ... when @list; } </code></pre> <hr> <h2>If you have to be able to run on older versions of Perl, there still are several options.</h2> <ul> <li><p>You might think you can get away with using <a href="http://perldoc.perl.org/List/Util.html#first-BLOCK-LIST" rel="noreferrer">List::Util::first</a>, but there are some edge conditions that make it problematic.</p> <p>In this example it is fairly obvious that we want to successfully match against <code>0</code>. Unfortunately this code will print <code>failure</code> every time.</p> <pre><code>use List::Util qw'first'; my $element = 0; if( first { $element eq $_ } 0..9 ){ print "success\n"; } else { print "failure\n"; } </code></pre> <p>You could check the return value of <a href="http://perldoc.perl.org/List/Util.html#first-BLOCK-LIST" rel="noreferrer"><code>first</code></a> for defined-ness, but that will fail if we actually want a match against <code>undef</code> to succeed.</p></li> <li><p>You can safely use <a href="http://perldoc.perl.org/functions/grep.html" rel="noreferrer"><code>grep</code></a> however.</p> <pre><code>if( grep { $element eq $_ } 0..9 ){ ... } </code></pre> <p>This is safe because <code>grep</code> gets called in a scalar context. Arrays return the number of elements when called in scalar context. So this will continue to work even if we try to match against <code>undef</code>.</p></li> <li><p>You could use an enclosing <code>for</code> loop. Just make sure you call <code>last</code>, to exit out of the loop on a successful match. Otherwise you might end up running your code more than once.</p> <pre><code>for( @array ){ if( $element eq $_ ){ ... last; } } </code></pre></li> <li><p>You could put the <code>for</code> loop inside the condition of the <code>if</code> statement ...</p> <pre><code>if( do{ my $match = 0; for( @list ){ if( $element eq $_ ){ $match = 1; last; } } $match; # the return value of the do block } ){ ... } </code></pre></li> <li><p>... but it might be more clear to put the <code>for</code> loop before the <code>if</code> statement.</p> <pre><code>my $match = 0; for( @list ){ if( $_ eq $element ){ $match = 1; last; } } if( $match ){ ... } </code></pre></li> <li><p>If you're only matching against strings, you could also use a hash. This can speed up your program if <code>@list</code> is large <strong>and</strong>, you are going to match against <code>%hash</code> several times. Especially if <code>@array</code> doesn't change, because then you only have to load up <code>%hash</code> once.</p> <pre><code>my %hash = map { $_, 1 } @array; if( $hash{ $element } ){ ... } </code></pre></li> <li><p>You could also make your own subroutine. This is one of the cases where it is useful to use <a href="http://perldoc.perl.org/perlsub.html#Prototypes" rel="noreferrer">prototypes</a>.</p> <pre><code>sub in(&amp;@){ local $_; my $code = shift; for( @_ ){ # sets $_ if( $code-&gt;() ){ return 1; } } return 0; } if( in { $element eq $_ } @list ){ ... } </code></pre></li> </ul>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload