summaryrefslogtreecommitdiff
path: root/pod/perlop.pod
diff options
context:
space:
mode:
authorZefram <zefram@fysh.org>2017-12-17 11:02:23 +0000
committerZefram <zefram@fysh.org>2017-12-17 11:02:23 +0000
commitda4e040f42421764ef069371d77c008e6b801f45 (patch)
treedad219b9c5a660c14705b6544fab2b3572bc2bd9 /pod/perlop.pod
parentb2cd5cb1d8b3c8a7a7f033784d5134d2fbd8cad8 (diff)
parentd6374f3d794e2a640258023e92e8d922409215ec (diff)
downloadperl-da4e040f42421764ef069371d77c008e6b801f45.tar.gz
merge branch zefram/dumb_match
Diffstat (limited to 'pod/perlop.pod')
-rw-r--r--pod/perlop.pod298
1 files changed, 17 insertions, 281 deletions
diff --git a/pod/perlop.pod b/pod/perlop.pod
index 188699cea2..c1868903ec 100644
--- a/pod/perlop.pod
+++ b/pod/perlop.pod
@@ -576,288 +576,24 @@ function, available in Perl v5.16 or later:
=head2 Smartmatch Operator
-First available in Perl 5.10.1 (the 5.10.0 version behaved differently),
-binary C<~~> does a "smartmatch" between its arguments. This is mostly
-used implicitly in the C<when> construct described in L<perlsyn>, although
-not all C<when> clauses call the smartmatch operator. Unique among all of
-Perl's operators, the smartmatch operator can recurse. The smartmatch
+Binary C<~~> does a "smartmatch" between its arguments. The smartmatch
operator is L<experimental|perlpolicy/experimental> and its behavior is
-subject to change.
-
-It is also unique in that all other Perl operators impose a context
-(usually string or numeric context) on their operands, autoconverting
-those operands to those imposed contexts. In contrast, smartmatch
-I<infers> contexts from the actual types of its operands and uses that
-type information to select a suitable comparison mechanism.
-
-The C<~~> operator compares its operands "polymorphically", determining how
-to compare them according to their actual types (numeric, string, array,
-hash, etc.) Like the equality operators with which it shares the same
-precedence, C<~~> returns 1 for true and C<""> for false. It is often best
-read aloud as "in", "inside of", or "is contained in", because the left
-operand is often looked for I<inside> the right operand. That makes the
-order of the operands to the smartmatch operand often opposite that of
-the regular match operator. In other words, the "smaller" thing is usually
-placed in the left operand and the larger one in the right.
-
-The behavior of a smartmatch depends on what type of things its arguments
-are, as determined by the following table. The first row of the table
-whose types apply determines the smartmatch behavior. Because what
-actually happens is mostly determined by the type of the second operand,
-the table is sorted on the right operand instead of on the left.
-
- Left Right Description and pseudocode
- ===============================================================
- Any undef check whether Any is undefined
- like: !defined Any
-
- Any Object invoke ~~ overloading on Object, or die
-
- Right operand is an ARRAY:
-
- Left Right Description and pseudocode
- ===============================================================
- ARRAY1 ARRAY2 recurse on paired elements of ARRAY1 and ARRAY2[2]
- like: (ARRAY1[0] ~~ ARRAY2[0])
- && (ARRAY1[1] ~~ ARRAY2[1]) && ...
- HASH ARRAY any ARRAY elements exist as HASH keys
- like: grep { exists HASH->{$_} } ARRAY
- Regexp ARRAY any ARRAY elements pattern match Regexp
- like: grep { /Regexp/ } ARRAY
- undef ARRAY undef in ARRAY
- like: grep { !defined } ARRAY
- Any ARRAY smartmatch each ARRAY element[3]
- like: grep { Any ~~ $_ } ARRAY
-
- Right operand is a HASH:
-
- Left Right Description and pseudocode
- ===============================================================
- HASH1 HASH2 all same keys in both HASHes
- like: keys HASH1 ==
- grep { exists HASH2->{$_} } keys HASH1
- ARRAY HASH any ARRAY elements exist as HASH keys
- like: grep { exists HASH->{$_} } ARRAY
- Regexp HASH any HASH keys pattern match Regexp
- like: grep { /Regexp/ } keys HASH
- undef HASH always false (undef can't be a key)
- like: 0 == 1
- Any HASH HASH key existence
- like: exists HASH->{Any}
-
- Right operand is CODE:
-
- Left Right Description and pseudocode
- ===============================================================
- ARRAY CODE sub returns true on all ARRAY elements[1]
- like: !grep { !CODE->($_) } ARRAY
- HASH CODE sub returns true on all HASH keys[1]
- like: !grep { !CODE->($_) } keys HASH
- Any CODE sub passed Any returns true
- like: CODE->(Any)
-
-Right operand is a Regexp:
-
- Left Right Description and pseudocode
- ===============================================================
- ARRAY Regexp any ARRAY elements match Regexp
- like: grep { /Regexp/ } ARRAY
- HASH Regexp any HASH keys match Regexp
- like: grep { /Regexp/ } keys HASH
- Any Regexp pattern match
- like: Any =~ /Regexp/
-
- Other:
-
- Left Right Description and pseudocode
- ===============================================================
- Object Any invoke ~~ overloading on Object,
- or fall back to...
-
- Any Num numeric equality
- like: Any == Num
- Num nummy[4] numeric equality
- like: Num == nummy
- undef Any check whether undefined
- like: !defined(Any)
- Any Any string equality
- like: Any eq Any
-
-
-Notes:
-
-=over
-
-=item 1.
-Empty hashes or arrays match.
-
-=item 2.
-That is, each element smartmatches the element of the same index in the other array.[3]
-
-=item 3.
-If a circular reference is found, fall back to referential equality.
-
-=item 4.
-Either an actual number, or a string that looks like one.
-
-=back
-
-The smartmatch implicitly dereferences any non-blessed hash or array
-reference, so the C<I<HASH>> and C<I<ARRAY>> entries apply in those cases.
-For blessed references, the C<I<Object>> entries apply. Smartmatches
-involving hashes only consider hash keys, never hash values.
-
-The "like" code entry is not always an exact rendition. For example, the
-smartmatch operator short-circuits whenever possible, but C<grep> does
-not. Also, C<grep> in scalar context returns the number of matches, but
-C<~~> returns only true or false.
-
-Unlike most operators, the smartmatch operator knows to treat C<undef>
-specially:
-
- use v5.10.1;
- @array = (1, 2, 3, undef, 4, 5);
- say "some elements undefined" if undef ~~ @array;
-
-Each operand is considered in a modified scalar context, the modification
-being that array and hash variables are passed by reference to the
-operator, which implicitly dereferences them. Both elements
-of each pair are the same:
-
- use v5.10.1;
-
- my %hash = (red => 1, blue => 2, green => 3,
- orange => 4, yellow => 5, purple => 6,
- black => 7, grey => 8, white => 9);
-
- my @array = qw(red blue green);
-
- say "some array elements in hash keys" if @array ~~ %hash;
- say "some array elements in hash keys" if \@array ~~ \%hash;
-
- say "red in array" if "red" ~~ @array;
- say "red in array" if "red" ~~ \@array;
-
- say "some keys end in e" if /e$/ ~~ %hash;
- say "some keys end in e" if /e$/ ~~ \%hash;
-
-Two arrays smartmatch if each element in the first array smartmatches
-(that is, is "in") the corresponding element in the second array,
-recursively.
-
- use v5.10.1;
- my @little = qw(red blue green);
- my @bigger = ("red", "blue", [ "orange", "green" ] );
- if (@little ~~ @bigger) { # true!
- say "little is contained in bigger";
- }
-
-Because the smartmatch operator recurses on nested arrays, this
-will still report that "red" is in the array.
-
- use v5.10.1;
- my @array = qw(red blue green);
- my $nested_array = [[[[[[[ @array ]]]]]]];
- say "red in array" if "red" ~~ $nested_array;
-
-If two arrays smartmatch each other, then they are deep
-copies of each others' values, as this example reports:
-
- use v5.12.0;
- my @a = (0, 1, 2, [3, [4, 5], 6], 7);
- my @b = (0, 1, 2, [3, [4, 5], 6], 7);
-
- if (@a ~~ @b && @b ~~ @a) {
- say "a and b are deep copies of each other";
- }
- elsif (@a ~~ @b) {
- say "a smartmatches in b";
- }
- elsif (@b ~~ @a) {
- say "b smartmatches in a";
- }
- else {
- say "a and b don't smartmatch each other at all";
- }
-
-
-If you were to set S<C<$b[3] = 4>>, then instead of reporting that "a and b
-are deep copies of each other", it now reports that C<"b smartmatches in a">.
-That's because the corresponding position in C<@a> contains an array that
-(eventually) has a 4 in it.
-
-Smartmatching one hash against another reports whether both contain the
-same keys, no more and no less. This could be used to see whether two
-records have the same field names, without caring what values those fields
-might have. For example:
-
- use v5.10.1;
- sub make_dogtag {
- state $REQUIRED_FIELDS = { name=>1, rank=>1, serial_num=>1 };
-
- my ($class, $init_fields) = @_;
-
- die "Must supply (only) name, rank, and serial number"
- unless $init_fields ~~ $REQUIRED_FIELDS;
-
- ...
- }
-
-However, this only does what you mean if C<$init_fields> is indeed a hash
-reference. The condition C<$init_fields ~~ $REQUIRED_FIELDS> also allows the
-strings C<"name">, C<"rank">, C<"serial_num"> as well as any array reference
-that contains C<"name"> or C<"rank"> or C<"serial_num"> anywhere to pass
-through.
-
-The smartmatch operator is most often used as the implicit operator of a
-C<when> clause. See the section on "Switch Statements" in L<perlsyn>.
-
-=head3 Smartmatching of Objects
-
-To avoid relying on an object's underlying representation, if the
-smartmatch's right operand is an object that doesn't overload C<~~>,
-it raises the exception "C<Smartmatching a non-overloaded object
-breaks encapsulation>". That's because one has no business digging
-around to see whether something is "in" an object. These are all
-illegal on objects without a C<~~> overload:
-
- %hash ~~ $object
- 42 ~~ $object
- "fred" ~~ $object
-
-However, you can change the way an object is smartmatched by overloading
-the C<~~> operator. This is allowed to
-extend the usual smartmatch semantics.
-For objects that do have an C<~~> overload, see L<overload>.
-
-Using an object as the left operand is allowed, although not very useful.
-Smartmatching rules take precedence over overloading, so even if the
-object in the left operand has smartmatch overloading, this will be
-ignored. A left operand that is a non-overloaded object falls back on a
-string or numeric comparison of whatever the C<ref> operator returns. That
-means that
-
- $object ~~ X
-
-does I<not> invoke the overload method with C<I<X>> as an argument.
-Instead the above table is consulted as normal, and based on the type of
-C<I<X>>, overloading may or may not be invoked. For simple strings or
-numbers, "in" becomes equivalent to this:
-
- $object ~~ $number ref($object) == $number
- $object ~~ $string ref($object) eq $string
-
-For example, this reports that the handle smells IOish
-(but please don't really do this!):
-
- use IO::Handle;
- my $fh = IO::Handle->new();
- if ($fh ~~ /\bIO\b/) {
- say "handle smells IOish";
- }
-
-That's because it treats C<$fh> as a string like
-C<"IO::Handle=GLOB(0x8039e0)">, then pattern matches against that.
+subject to change. It first became available in Perl 5.10, but prior
+to Perl 5.28 its behaviour was quite different from its present behaviour.
+
+The C<~~> operator applies some kind of matching criterion to its
+left-hand operand, and returns a truth value result. The criterion to
+apply is determined by the right-hand operand, which must be a reference
+to an object blessed into a class that overloads the C<~~> operator for
+this purpose. The class into which compiled regexp objects are blessed
+by the C<qr//> operator has such an overloading, which checks whether
+the left-hand operand matches the regexp. If the right-hand operand is
+not a reference to such a matcher object, an exception is raised.
+
+Overloading of C<~~> only applies when the object reference is the
+right-hand operand. An object reference as the left-hand operand is
+subjected to whatever criterion is specified by the right-hand operand,
+regardless of its own overloading.
=head2 Bitwise And
X<operator, bitwise, and> X<bitwise and> X<&>