📜 ⬆️ ⬇️

Perl 6 and smart match

Do you remember an article about the sequence operator in Perl 6?

With the final argument, it takes a constraint that stops the generation of the sequence. For example

1, 2, 4 ... 32; # 1 2 4 8 16 32 1, 2, 4 ... * > 10; # 1 2 4 8 16 

')
In the first case, a numerical comparison is used. In the second, the entry *> 10 is interpreted as closure -> $ x {$ x> 10}.

The sequence operator performs a "magic" comparison depending on the type of match. This comparison is called “smart matching” (“smartmatching”), and this concept appears in many places in Perl 6. Examples:

  #    'when': given $age { when 100 { say "!" } when * < 18 { say " " } } #  'where': subset Even of Int where * %% 2; #    smartmatch: if $input ~~ m/^\d+$/ { say "$input –  "; } #   grep(), first()  ..: my @even = @numbers.grep: Even; 


On the right side of ~~ and after when and where, the compared value is taken from $ _. This allows us to create constructions that work with $ _, such as regulars created via m /.../ and .method_call.

Examples of using the operator:

  #     Str? $foo ~~ Str #    6? $foo ~~ 6 #   "bar"? $foo ~~ "bar" #   ? $foo ~~ / \w+ '-' \d+ / #    15  25? $foo ~~ (15..25) #   $foo ~~ -> $x { say 'ok' if 5 < $x < 25 } #      6 ,       1? $foo ~~ [1, *, 1, *, 1, *] 


Detailed table for the operator.

Note that unlike Perl 5, in Perl 6, smartmatching is the only way to compare something to regular, there is no special operator for that. In addition, although most smartmatching operations return Bool, comparison with a regular routine returns a Match object. Which, moreover, behaves correctly in a boolean context.

Okay, and how to use it not with built-in types, but with your own classes? For this you need to write a special method, ACCEPTS. Suppose we have the good old class Point:

  class Point { has $.x; has $.y; method ACCEPTS(Positional $p2) { return $.x == $p2[0] and $.y == $p2[1] } } 


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 


Now Perl 6 can do exactly what you meant, even with your own classes.

Source: https://habr.com/ru/post/254029/


All Articles