Friday, 16 April 2010

perl smart matching (copied from perlsyn.pod)

Smart matching in detail

The behaviour of a smart match depends on what type of thing its arguments are. The behaviour is determined by the following table: the first row that applies determines the match behaviour (which is thus mostly determined by the type of the right operand). Note that the smart match implicitly dereferences any non-blessed hash or array ref, so the "Hash" and "Array" entries apply in those cases. (For blessed references, the "Object" entries apply.)
Note that the "Matching Code" column is not always an exact rendition. For example, the smart match operator short-circuits whenever possible, but grep does not.
$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 keys intersection   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 keys intersection   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

No comments: