Skip to content

Commit e0776d5

Browse files
committed
Merge branch 'master' of github.com:perl6/doc
2 parents 054585c + 16f15df commit e0776d5

File tree

5 files changed

+68
-27
lines changed

5 files changed

+68
-27
lines changed

doc/Language/containers.pod6

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -324,17 +324,31 @@ last resort, you can use Promises to L<handle|/type/Promise#method_in> timeouts.
324324
Any container can have a type constraint in the form of
325325
a L<type object|/language/typesystem#Type_objects> or a L<subset|/language/typesystem#subset>.
326326
Both can be placed between a declarator and the variable name or after the trait L<of|/type/Variable#trait_is_dynamic>.
327-
The constraint is a property of the container, not the variable. Any (re-)binding may change the
328-
type constraint or remove the constraint altogether if bound to a value instead of a container.
329-
Introspection of type constraints on containers is provided by C<.VAR.of>.
330-
331-
EVAL ‚my Int $i = 42; $i := "forty plus two";‘;
332-
CATCH { default { say .^name, ' ', .Str } }
333-
# OUTPUT: «Type check failed in binding; expected Int but got Str ("forty plus two")␤…»
334-
335-
The default type constraint of a C<Scalar> container is Any. For &-sigiled
336-
containers it's C<Callable> and @-sigiled containers are of type C<Array>. Please
337-
note that binding can change the type constraint.
327+
The constraint is a property of the container, not the variable.
328+
329+
Variables may have no container in them, yet still offer the ability to
330+
re-bind and typecheck that rebind. The reason for that is in such cases the
331+
binding operator L<:=|/operators#infix_:=> performs the typecheck:
332+
333+
my Int \z = 42;
334+
z := 100; # OK
335+
z := "x"; # Typecheck failure
336+
337+
The same isn't the case when, say, binding to a L<Hash> key, as there the
338+
binding is handled by a method call (even though the syntax remains the same,
339+
using C<:=> operator).
340+
341+
The default type constraint of a C<Scalar> container is L<Mu>.
342+
Introspection of type constraints on containers is provided by C<.VAR.of>
343+
method, which for C<@> and C<%> sigiled variables gives the constraint for
344+
values:
345+
346+
my Str $x;
347+
say $x.VAR.of; # OUTPUT: «(Str)␤»
348+
my Num @a;
349+
say @a.VAR.of; # OUTPUT: «(Num)␤»
350+
my Int %h;
351+
say %h.VAR.of; # OUTPUT: «(Int)␤»
338352
339353
=head1 Custom containers
340354

doc/Language/modules.pod6

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ lib
592592
library files and their installed location can be determined through the
593593
C<%?RESOURCES> Hash indexed on the name provided. C<tags> is also optional, but is used to describe the module in the Perl6 ecosystem.
594594
595-
C<depends>, C<build-depends> and C<test-depends> include different modules that are used in those phases of the of installation. The last two are optional, but convenient.
595+
C<depends>, C<build-depends> and C<test-depends> include different modules that are used in those phases of the of installation. The last two are optional, but convenient.
596596
597597
The L<Test::META module | https://github.com/jonathanstowe/Test-META/>
598598
can help you check the correctness of the META6.json file.

doc/Language/operators.pod6

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2290,6 +2290,9 @@ different.
22902290
This will output 43, since C<$b> and C<$a> both represented the same
22912291
object.
22922292
2293+
If type constrains on variables or containers are present a type check will be
2294+
performed at runtime. On failure C<X::TypeCheck::BindingType> will be thrown.
2295+
22932296
Please note that C<:=> is a compile time construct. As such it can not be
22942297
referred to at runtime and thus can't be used as an argument to meta operators.
22952298

doc/Language/traps.pod6

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,30 +1391,52 @@ beware unintentional combination of C<LEAVE> phasers and C<exit> calls.
13911391
13921392
=head2 C<LEAVE> phaser may run sooner than you think
13931393
1394-
You should always expect the C<LEAVE> phaser to be executed before
1395-
I<anything> else in the block.
1394+
Parameter binding is executed when we're "inside" the routine's block,
1395+
which means C<LEAVE> phaser would run when we leave that block if parameter
1396+
binding fails when wrong arguments are given:
13961397
1397-
Here is an example:
1398+
=begin code
1399+
sub foo(Int) {
1400+
my $x = 42;
1401+
LEAVE say $x.Int; # ← WRONG; assumes that $x is set
1402+
}
1403+
say foo rand; # OUTPUT: «No such method 'Int' for invocant of type 'Any'␤»
1404+
=end code
1405+
1406+
A simple way to avoid this issue is to declare your sub or method a multi,
1407+
so the candidate is eliminated during dispatch and the code never gets to
1408+
binding anything inside the sub, thus never entering the routine's body:
13981409
13991410
=begin code
1400-
sub foo($ where ‘abc’) {
1411+
multi foo(Int) {
14011412
my $x = 42;
1402-
LEAVE say $x.Int; # ← WRONG; assumes that $x is not Nil
1413+
LEAVE say $x.Int;
14031414
}
1404-
say foo ‘hello’; # OUTPUT: «No such method 'Int' for invocant of type 'Any'␤»
1415+
say foo rand; # OUTPUT: «Cannot resolve caller foo(Num); none of these signatures match: (Int)␤»
14051416
=end code
14061417
1407-
You may think that there is no way C<my $x = 42> can fail, and
1408-
therefore C<$x> will always be defined in the C<LEAVE> block. But that
1409-
is simply not the case. There is no guarantee that anything will be
1410-
executed at all, which is what happens when type constraints are
1411-
involved.
1418+
Another alternative is placing the C<LEAVE> into another block (assuming it's
1419+
appropriate for it to be executed when I<that> block is left, not the
1420+
routine's body:
1421+
1422+
=begin code
1423+
sub foo(Int) {
1424+
my $x = 42;
1425+
{ LEAVE say $x.Int; }
1426+
}
1427+
say foo rand; # OUTPUT: «Type check failed in binding to parameter '<anon>'; expected Int but got Num (0.7289418947969465e0)␤»
1428+
=end code
14121429
1413-
The right way to do it is to I<always> check that whatever you use in
1414-
your C<LEAVE> block is defined:
1430+
You can also ensure C<LEAVE> can be executed even if the routine is left
1431+
due to failed argument binding. In our example, we check C<$x>
1432+
L<is defined|/routine/andthen> before doing anything with it.
14151433
1416-
=begin code :skip-test
1417-
LEAVE say .Int with $x
1434+
=begin code
1435+
sub foo(Int) {
1436+
my $x = 42;
1437+
LEAVE $x andthen .Int.say;
1438+
}
1439+
say foo rand; # OUTPUT: «Type check failed in binding to parameter '<anon>'; expected Int but got Num (0.8517160389079508e0)␤»
14181440
=end code
14191441
14201442
=head1 Grammars

xt/words.pws

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ bigrat
112112
bindkey
113113
bindoruse
114114
binmode
115+
bitbucket
115116
bitwise
116117
bom
117118
bool
@@ -1054,6 +1055,7 @@ smartmatching
10541055
smtp
10551056
socketpair
10561057
solitaryquantifier
1058+
someauthor
10571059
sourcecode
10581060
spdx
10591061
spectest

0 commit comments

Comments
 (0)