Remember the http://perl6advent.wordpress.com/2010/12/04/the-sequence-operator/ sequence operator? As the last argument it takes a limit, which makes the sequence generation stop. For example:
1, 2, 4 ... 32; # 1 2 4 8 16 32
1, 2, 4 ... * > 10; # 1 2 4 8 16
You can see that in the first case, numerical equality is used. The second is a bit more interesting: * > 10 is internally rewritten into a closure like -> $x { $x > 10 } (through currying).
The sequence operator then does some magic comparison, depending on the type of the matcher. This comparison is called "smartmatching", and is a concept that reappears in many places in Perl 6. Examples:
# after the 'when' keyword:
given $age {
when 100 { say "congratulations!" }
when * < 18 { say "You're not of age yet" }
}
# after 'where':
subset Even of Int where * %% 2;
# with an explicit smartmatch operator:
if $input ~~ m/^\d+$/ {
say "$input is an integer";
}
# arguments to grep(), first() etc.:
my @even = @numbers.grep: Even;
On the right-hand side of the ~~ operator, and after when and where, the value to be matched against is set to the topic variable $_. This allows us to use constructs that operate on $_, like regexes created with m/.../ and .method_call.
Here is what the smart match operator does with some matchers on the right-hand side:
# is it of type Str?
$foo ~~ Str
# is it equal to 6?
$foo ~~ 6
# or is it "bar"?
$foo ~~ "bar"
# does it match some pattern?
$foo ~~ / \w+ '-' \d+ /
# Is it between 15 and 25?
$foo ~~ (15..25)
# call a closure
$foo ~~ -> $x { say 'ok' if 5 < $x < 25 }
# is it an array of 6 elems in which every odd element is 1?
$foo ~~ [1, *, 1, *, 1, *]
The full table for smart matching behavior can be found at
http://perlcabal.org/syn/S03.html#Smart_matching.
Notice how, unlike in Perl 5, in Perl 6 smartmatching is the only syntactic way to match a regex, it has no special operator. Also, while most smart matching cases return a Bool, matching against a regex returns a Match object – which behaves appropriately in boolean context too.
You have probably started wondering: a’right, that for built-in types, how do I use it in my own classes? You need to write a special ACCEPTS method for it. Say we have our good, old class Point:
class Point {
has $.x;
has $.y;
method ACCEPTS(Positional $p2) {
return $.x == $p2[0] and $.y == $p2[1]
}
}
Everything clear? Let’s see how it works:
my $a = Point.new(x => 7, y => 9);
say [3, 5] ~~ $a; # Bool::False
say (7, 9) ~~ $a; # Bool::True
Perl 6 can now do exactly what you mean, even with your own classes.
December 26, 2010 at 6:42 pm |
I think you mean ‘smartmatch’ rather than ‘smartmath’ about 3/4 of the way down.
But it’s an interesting pun, given the discussion of autogenerated sequences like 1, 2, 4 … 32;
December 26, 2010 at 6:50 pm |
Fixed, thanks :)