Smart matching 

$a      $b        Type of Match Implied    Matching Code
======  =====     =====================    =============
Any     undef     undefined                !defined $a

Any     Object    invokes ~~ overloading on $object, or dies

Hash    CodeRef   sub truth for each key[1] !grep { !$b->($_) } keys %$a
Array   CodeRef   sub truth for each elt[1] !grep { !$b->($_) } @$a
Any     CodeRef   scalar sub truth          $b->($a)

Hash    Hash      hash keys identical (every key is found in both hashes)
Array   Hash      hash slice existence     grep { exists $b->{$_} } @$a
Regex   Hash      hash key grep            grep /$a/, keys %$b
undef   Hash      always false (undef can't be a key)
Any     Hash      hash entry existence     exists $b->{$a}

Hash    Array     hash slice existence     grep { exists $a->{$_} } @$b
Array   Array     arrays are comparable[2]
Regex   Array     array grep               grep /$a/, @$b
undef   Array     array contains undef     grep !defined, @$b
Any     Array     match against an array element[3]
                                           grep $a ~~ $_, @$b

Hash    Regex     hash key grep            grep /$b/, keys %$a
Array   Regex     array grep               grep /$b/, @$a
Any     Regex     pattern match            $a =~ /$b/

Object  Any       invokes ~~ overloading on $object, or falls back:
Any     Num       numeric equality         $a == $b
Num     numish[4] numeric equality         $a == $b
undef   Any       undefined                !defined($b)
Any     Any       string equality          $a eq $b

1 - empty hashes or arrays will match.
2 - that is, each element smart-matches the element of same index in the
 other array. [3]
3 - If a circular reference is found, we fall back to referential equality.
4 - either a real number, or a string that looks like a number