-
Notifications
You must be signed in to change notification settings - Fork 292
/
Parameter.pod6
287 lines (189 loc) · 8.46 KB
/
Parameter.pod6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
=begin pod
=TITLE class Parameter
=SUBTITLE Element of a Signature
class Parameter { }
Represents a parameter, for purpose of introspection.
The usual way to obtain a Parameter object is to create a signature,
and call C<.params> on it to obtain a list of the Parameters.
my $sig = :(Str $x);
my $param = $sig.params[0];
say $param.type; # OUTPUT: «Str()»
See L<Signature> for more information, and also for an explanation
on what most of the concepts related to parameters mean.
=head1 Methods
=head2 method name
Returns the variable name, which includes all sigils and twigils.
This name is used internally when applied to code, or in a declaration
determines the name declared. This name is not necessarily
usable by a caller – if it is, it will also appear as an
L<alias|#method named_names>. Often, the name will chosen descriptively
as a form of self-documentation.
If the parameter is anonymous, C<Nil> will be returned.
=head2 method sigil
Defined as:
method sigil(Parameter:D: --> Str:D)
Returns a string containing the parameter's sigil, for a looser
definition of "sigil" than what is considered part of
the variable's C<name|method name>. Still returns a sigil even
if the parameter is anonymous.
This "sigil" is actually an introspection used to help determine
the normal binding style of a parameter, if it has not been altered
through a L<trait|/type/Signature#Parameter_traits_and_modifiers>.
=begin table
Sigil | Will bind to | Default behavior
===================================================
$ | Scalar | Generate new Scalar, use instead of Scalar in argument, if any
@ | Positional | Bind directly to the argument
@ | PositionalBindFailover | If binding failed, call argument's .cache method, bind to result
% | Associative | Bind directly to the argument
& | Callable | Bind directly to the argument
\ | (anything) | Bind directly to the argument, keep existing Scalar, if any
=end table
Also, C<|> will bind to all remaining arguments, make new C<Capture> if needed.
=head2 method type
Returns the L<nominal type constraint|/type/Signature#Type_constraints> of
the parameter.
=head2 method constraints
Returns L<additional constraints|/type/Signature#Type_constraints> on the
parameter (usually as an C<all>-Junction).
=head2 method named
Defined as:
method named(Parameter:D: --> Bool:D)
Returns C<True> if it's a L<named parameter|/type/Signature#Positional_vs._named_arguments>.
my Signature $sig = :(Str $x, Bool :$is-named);
say $sig.params[0].named; # OUTPUT: «False»
say $sig.params[1].named; # OUTPUT: «True»
=head2 method named_names
Defined as:
method named_names(Parameter:D: --> List:D)
Returns the list of externally usable names/aliases for a
L<named parameter|/type/Signature#Positional_vs._named_arguments>.
=head2 method positional
Defined as:
method positional(Parameter:D: --> Bool:D)
Returns C<True> if the parameter is
L<positional|/type/Signature#Positional_vs._named_arguments>.
my Signature $sig = :(Str $x, Bool :$is-named);
say $sig.params[0].positional; # OUTPUT: «True»
say $sig.params[1].positional; # OUTPUT: «False»
=head2 method slurpy
Defined as:
method slurpy(Parameter:D: --> Bool:D)
Returns C<True> for
L<slurpy parameters|/type/Signature#Slurpy_(A.K.A._variadic)_parameters>.
=head2 method twigil
Defined as:
method twigil(Parameter:D: --> Str:D)
Returns a string containing the twigil part of the parameter's name.
=head2 method optional
Defined as:
method optional(Parameter:D: --> Bool:D)
Returns C<True> for
L<optional parameters|/type/Signature#Optional_and_Mandatory_Parameters>.
=head2 method raw
Defined as:
method raw(Parameter:D: --> Bool:D)
Returns C<True> for raw parameters.
sub f($a, $b is raw, \c) {
my $sig = &?ROUTINE.signature;
for ^$sig.params.elems {
say $sig.params[$_].raw;
}
}
f(17, "4711", 42); OUTPUT: «FalseTrueTrue»
Raw parameters bind either a variable or a value passed to it, with
no decontainerization taking place. That means that if a variable was passed
to it, you can assign to the parameter. This is different from
L<rw|#method_rw>-parameter which can only bind to variables, never to values.
This is the normal behavior for parameters declared with a
L<sigil|#method sigil> of C<'\'>, which is not really a sigil insofar
as it is only used on the parameter.
sub f(\x) {
x = 5;
}
f(my $x); # works
f(42); # dies
CATCH { default { put .^name, ': ', .Str } };
# OUTPUT: «X::Assignment::RO: Cannot modify an immutable Int»
Other parameters may become raw through use of the 'C<is raw>'
L<trait|/type/Signature#Parameter_Traits_and_Modifiers>. These still use
their sigil in code.
sub f($x is raw) {
$x = 5;
}
=head2 method capture
Defined as:
method capture(Parameter:D: --> Bool:D)
Returns C<True> for parameters that capture the rest of the argument list into
a single L<Capture|/type/Capture> object.
sub how_many_extra_positionals($!, |capture) { capture.elems.say }
how_many_extra_positionals(0, 1, 2, 3); # RESULT: «3»
say &how_many_extra_positionals.signature.params[1].capture; # OUTPUT: «True»
Like raw parameters, Capture parameters do not force any context on the
values bound to them, which is why their sigils are only used in
declarations.
=head2 method rw
Defined as:
method rw(Parameter:D: --> Bool:D)
Returns C<True> for L<C<is rw>|/type/Signature#Parameter_Traits_and_Modifiers>
parameters.
my Signature $sig = :(Str $x is rw, Bool :$is-named);
say $sig.params[0].rw; # OUTPUT: «True»
say $sig.params[1].rw; # OUTPUT: «False»
=head2 method copy
Defined as:
method copy(Parameter:D: --> Bool:D)
Returns C<True> for L<C<is copy>|/type/Signature#Parameter_Traits_and_Modifiers>
parameters.
my Signature $sig = :(Str $x, Bool :$is-named is copy);
say $sig.params[0].copy; # OUTPUT: «False»
say $sig.params[1].copy; # OUTPUT: «True»
=head2 method readonly
Defined as:
method readonly(Parameter:D: --> Bool:D)
Returns C<True> for read-only parameters (the default).
my Signature $sig = :(Str $x is rw, Bool :$is-named);
say $sig.params[0].readonly; # OUTPUT: «False»
say $sig.params[1].readonly; # OUTPUT: «True»
=head2 method invocant
Defined as:
method invocant(Parameter:D: --> Bool:D)
Returns C<True> if the parameter is the
L<invocant parameter|/type/Signature#Parameter_Separators>.
=head2 method default
Returns a closure that upon invocation returns the
L<default value|/type/Signature#Optional_and_Mandatory_Parameters> for
this parameter, or C<Any> if no default was provided.
=head2 method type_captures
Defined as:
method type_captures(Parameter:D: --> List:D)
Returns a list of variable names of type captures associated with this
parameter. Type captures define a type name within the attached code,
which is an alias to the type gleaned from the argument during a call.
sub a(::T ::U $x) { T.say }
a(8); # OUTPUT: «(Int)»
say &a.signature.params[0].type_captures; # OUTPUT: «(T U)»
sub b($x) { $x.^name.say }
a(8); # OUTPUT: «Int»
The type used may change from call to call. Once they are defined,
type captures can be used wherever you would use a type, even later
in same the signature:
=for code
sub c(::T $x, T $y, $z) { my T $zz = $z };
c(4, 5, 6); # OK
c(4, 5, "six"); # Fails when assigning to $zz, wants Int not Str
c("four", 5, "six"); # Fails when binding $y, wants Str, not Int
Type captures may be used at the same time as
L<type constraints|/type/Signature#Type_Constraints>.
=for code
sub d(::T Numeric $x, T $y) {};
d(4, 5); # OK
d(4e0, 5e0); # OK
d(4e0, 5); # Fails when binding $y
d("four", "five"); # Fails when binding $x
=head2 method sub_signature
If the parameter has a
L<sub-signature|/type/Signature#Destructuring_Parameters>,
returns a C<Signature> object for it. Otherwise returns C<Any>.
=end pod
# vim: expandtab softtabstop=4 shiftwidth=4 ft=perl6