Perl 5.10 introduces a new-operator, called smart-match, written
~~. As the name suggests, smart-match tries to compare its
arguments in an intelligent fashion. Using smart-match effectively
allows many complex operations to be reduces to very simple statements.
Unlike many of the other features introduced in Perl 5.10, there's
no need to use the feature pragma to enable smart-match,
as long as you're using 5.10 it's available.
The smart-match operator is always commutative. That means that
$x ~~ $y works the same way as $y ~~ $x. You'll never have to
remember which order to place to your operands with smart-match.
As a simple introduction, we can use smart-match to do a simple string comparison between simple scalars. For example:
use feature qw(say);
my $x = "foo";
my $y = "bar";
my $z = "foo";
say '$x and $y are identical strings' if $x ~~ $y;
say '$x and $z are identical strings' if $x ~~ $z; # Printed
If one of our arguments is a number, then a numeric comparison is performed:
my $num = 100;
my $input = <STDIN>;
say 'You entered 100' if $num ~~ $input;
This will print our message if our user enters 100, 100.00, +100,
1e2, or any other string that looks like the number 100. We can
also smart-match against a regexp:
my $input = <STDIN>;
say 'You said the secret word!' if $input ~~ /xyzzy/;
Smart-matching with a regexp also works with saved regexps created
with qr{}.
So we can use smart-match to act like eq, == and =~, so what? Well,
it does much more than that. We can use smart-match to search
a list:
my @friends = qw(Frodo Meriadoc Pippin Samwise Gandalf);
my $name = <STDIN>;
chomp($name);
say "You're a friend" if $name ~~ @friends;
It's important to note that searching an array with smart-match is
extremely fast. It's faster than using grep, it's faster than
using first from <Scalar::Util>, and it's faster than
walking through the loop with foreach, even if you do know all
the clever optimisations.
We can also use smart-match to compare arrays:
my @foo = qw(x y z xyzzy ninja);
my @bar = qw(x y z xyzzy ninja);
say "Identical arrays" if @foo ~~ @bar;
And even search inside an array using a string:
say "Array contains a ninja " if @foo ~~ 'ninja';
or using a regexp:
say "Array contains magic pattern" if @foo ~~ /xyz/;
Smart-match works with array references, too:
my $array_ref = [5, 10, 15];
say "Array contains 10" if $array_ref ~~ 10;
Of course, we can use smart-match with more than just arrays and scalars, it works with searching for the key in a hash, too!
my %colour = (
sky => 'blue',
grass => 'green',
apple => 'red',
);
my $input = <STDIN>;
chomp $input;
say "I know the colour of $input" if $input ~~ %colour;
say "A key starts with 'gr'" if %colour ~~ /^gr/;
You can even use it to see if the two hashes have identical keys:
my %taste = (
grass => 'boring',
apple => 'yummy',
sky => undef,
);
say 'Hashes have identical keys' if %taste ~~ %colour;
You can even overload the smart-match operator to define what constitutes 'smart' for a given class of objects, although doing so is beyond the scope of this tip.
You can learn more about smart-match in the Smart matching in detail
section of perldoc perlsyn if you have Perl 5.10 installed, or you
can read about it on-line at http://search.cpan.org/~rgarcia/perl-5.10.0/pod/perlsyn.pod#Smart_matching_in_detail.
| Location | Course | Course Date | Duration | Early Bird Date |
|---|---|---|---|---|
| Melbourne | Object Oriented Perl | Tue 20 May 2008 | 2 days | — |
| Melbourne | Programming Perl | Tue 3 Jun 2008 | 4 days | — |
| Sydney | Object Oriented Perl | Tue 17 Jun 2008 | 2 days | Mon 26 May 2008 |
| Sydney | Database Programming with Perl | Thu 19 Jun 2008 | 2 days | Mon 26 May 2008 |
| Sydney | Programming Perl | Tue 1 Jul 2008 | 4 days | Mon 9 Jun 2008 |
| Melbourne | Programming Perl | Tue 2 Sep 2008 | 4 days | Mon 4 Aug 2008 |
For future dates, please see our training calendar.
This Perl tip and associated text is copyright Perl Training Australia. You may freely distribute this text so long as it is distributed in full with this Copyright noticed attached.
If you have any questions please don't hesitate to contact us:
| Email: | contact@perltraining.com.au |
| Phone: | 03 9354 6001 |
Copyright 2001-2008 Perl Training Australia. Contact us at contact@perltraining.com.au