develooper Front page | perl.perl5.porters | Postings from December 2005

[PATCH] switch / ~~ doccos

Thread Next
From:
Robin Houston
Date:
December 21, 2005 05:52
Subject:
[PATCH] switch / ~~ doccos
How does this look?

Robin

--- perl-before/pod/perlsyn.pod	2005-12-19 19:27:35.000000000 +0000
+++ perl-after/pod/perlsyn.pod	2005-12-21 13:42:41.000000000 +0000
@@ -511,17 +511,49 @@
 
 This construct is very flexible and powerful. For example:
 
-    given() {
-	xxxx
+    use feature ":5.10";
+    given($foo) {
+	when (undef) {
+	    say '$foo is undefined';
+	}
+
+	when ("foo") {
+	    say '$foo is the string "foo"';
+	}
+	
+	when ([1,3,5,7,9]) {
+	    say '$foo is an odd digit';
+	    continue; # Fall through
     }
 
-Most of its power comes from the implicit smart matching:
+	when ($_ < 100) {
+	    say '$foo is numerically less than 100';
+	}
+	
+	when (\&complicated_check) {
+	    say 'complicated_check($foo) is true';
+	}
 
-	when($foo) ...
+	default {
+	    die q(I don't know what to do with $foo);
+	}
+    }
+
+C<given(EXPR)> will assign the value of EXPR to C<$_>
+within the lexical scope of the block, so it's similar to
+
+	do { my $_ = EXPR; ... }
+
+except that the block is automatically roken out of by a 
+successful C<when> or an explicit C<break>.
+
+Most of the power comes from implicit smart matching:
+
+	when($foo)
 
 is exactly equivalent to
 
-	when($_ ~~ $foo) ...
+	when($_ ~~ $foo)
 
 (though you need to enable the "~~" feature before you
 can use the C<~~> operator directly). In fact C<when(EXPR)>
@@ -541,7 +573,8 @@
 
 =item o
 
-a comparison (such as C<$_ E<lt> 10> or C<$x gt "abc">
+a comparison such as C<$_ E<lt> 10> or C<$x eq "abc">
+(or of course C<$_ ~~ $c>)
 
 =item o
 
@@ -578,21 +611,32 @@
 
     when (/^\d$/ && $_ < 75) { ... }
 
+Another useful shortcut is that, if you use a literal array
+or hash as the argument to C<when>, it is turned into a
+reference. So C<given(@foo)> is the same as C<given(\@foo)>,
+for example.
+
 C<default> behaves exactly like C<when(1 == 1)>, which is
 to say that it always matches.
 
 See L</"Smart matching in detail"> for more information
 on smart matching.
 
+=head3 Breaking out
+
+You can use the C<break> keyword to break out of the enclosing
+C<given> block.  Every C<when> block is implicitly ended with
+a C<break>.
+
 =head3 Fall-through
 
 You can use the C<continue> keyword to fall through from one
 case to the next:
 
     given($foo) {
-	when (/x/) { print "\$foo contains an 'x'\n"; continue }
-	when (/y/) { print "\$foo contains a 'y'\n" }
-	default    { print "\$foo contains neither an 'x' nor a 'y' }
+	when (/x/) { say '$foo contains an x'; continue }
+	when (/y/) { say '$foo contains a y' }
+	default    { say '$foo contains neither an x nor a y' }
     }
 
 =head3 Switching in a loop
@@ -617,12 +661,55 @@
 
 =head3 Smart matching in detail
 
-
+The behaviour of a smart match depends on what type of thing
+its arguments are. It is always commutative, i.e. C<$a ~~ $b>
+behaves the same as C<$b ~~ $a>. The behaviour is determined
+by the following table: the first row that applies, in either
+order, determines the match behaviour.
+
+
+    $a      $b        Type of Match Implied    Matching Code
+    ======  =====     =====================    =============
+    (overloading trumps everything)
+
+    Code[+] Code[+]   referential equality     $a == $b
+    Any     Code[+]   scalar sub truth         $b->($a)
+
+    Hash    Hash      hash keys identical      [sort keys %$a]~~[sort keys %$b]
+    Hash    Array     hash value slice truth   grep $_, @$a{@$b}
+    Hash    Regex     hash key grep            grep /$b/, keys %$a
+    Hash    Any       hash entry existence     exists $a->{$b}
+
+    Array   Array     arrays are identical[*]
+    Array   Regex     array grep               grep /$b/, @$a
+    Array   Num       array contains number    grep $_ == $b, @$a
+    Array   Any       array contains string    grep $_ eq $b, @$a
+
+    Any     undef     undefined                !defined $a
+    Any     Regex     pattern match            $a =~ /$b/
+    Code()  Code()    results are equal        $a->() eq $b->()
+    Any     Code()    simple closure truth     $b->() # ignoring $a
+    Num     numish[!] numeric equality         $a == $b
+    Any     Str       string equality          $a eq $b
+    Any     Num       numeric equality         $a == $b
+
+    Any     Any       string equality          $a eq $b
+
+
+ + - this must be a code reference whose prototype (if present) is not ""
+     (subs with a "" prototype are dealt with by the 'Code()' entry lower down)
+ * - if a circular reference is found, we fall back to referential equality
+ ! - either a real number, or a string that looks like a number
+
+The "matching code" doesn't represent the I<real> matching code,
+of course: it's just there to explain the intended meaning. Unlike
+C<grep>, the smart match operator will short-circuit whenever it can.
 
 =head3 Custom matching via overloading
 
 You can change the way that an object is matched by overloading
-the C<'~~'> operator. This trumps the usual smart match semantics.
+the C<~~> operator. This trumps the usual smart match semantics.
+See L<overload>.
 
 =head2 Goto
 X<goto>

Thread Next


Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About