/
Code.pod6
225 lines (147 loc) · 6.82 KB
/
Code.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
=begin pod :kind("Type") :subkind("class") :category("basic")
=TITLE class Code
=SUBTITLE Code object
class Code is Any does Callable {}
C<Code> is the ultimate base class of all code objects in Raku. It
exposes functionality that all code objects have. While thunks are
directly of type C<Code>, most code objects (such as those resulting
from blocks, subroutines or methods) will belong to some subclass of C<Code>.
=head1 Methods
=head2 method ACCEPTS
multi method ACCEPTS(Code:D: Mu $topic)
Usually calls the code object and passes C<$topic> as an argument.
However, when called on a code object that takes no arguments, the code
object is invoked with no arguments and C<$topic> is dropped. The
result of the call is returned.
=head2 method arity
Defined as:
method arity(Code:D: --> Int:D)
Returns the minimum number of positional arguments that must be passed
in order to call the code object. Any optional or slurpy parameters in the
code object's C<Signature> do not contribute, nor do named parameters.
sub argless() { }
sub args($a, $b?) { }
sub slurpy($a, $b, *@c) { }
say &argless.arity; # OUTPUT: «0»
say &args.arity; # OUTPUT: «1»
say &slurpy.arity; # OUTPUT: «2»
=head2 method assuming
method assuming(Callable:D $self: |primers)
Returns a C<Callable> that implements the same behavior as the
original, but has the values passed to .assuming already bound to the
corresponding parameters.
my sub slow($n){ my $i = 0; $i++ while $i < $n; $i };
# takes only one parameter and as such wont forward $n
sub bench(&c){ c, now - ENTER now };
say &slow.assuming(10000000).&bench; # OUTPUT: «(10000000 7.5508834)»
For a sub with arity greater than one, you can use C<Whatever> C<*> for all of
the positional parameters that are not "assumed".
sub first-and-last ( $first, $last ) {
say "Name is $first $last";
}
my &surname-smith = &first-and-last.assuming( *, 'Smith' );
&surname-smith.( 'Joe' ); # OUTPUT: «Name is Joe Smith»
You can handle any combination of assumed and not assumed positional parameters:
=begin code
sub longer-names ( $first, $middle, $last, $suffix ) {
say "Name is $first $middle $last $suffix";
}
my &surname-public = &longer-names.assuming( *, *, 'Public', * );
&surname-public.( 'Joe', 'Q.', 'Jr.'); # OUTPUT: «Name is Joe Q. Public Jr.»
=end code
Named parameters can be assumed as well:
sub foo { say "$^a $^b $:foo $:bar" }
&foo.assuming(13, :42foo)(24, :72bar); # OUTPUT: «13 24 42 72»
And you can use C<.assuming> on all types of L<Callables|/type/Callable>,
including L<Methods|/type/Method> and L<Blocks|/type/Block>:
# We use a Whatever star for the invocant:
my &comber = Str.^lookup('comb').assuming: *, /P \w+/;
say comber 'Perl is awesome! Python is great! And PHP is OK too';
# OUTPUT: «(Perl Python PHP)»
my &learner = {
"It took me $:months months to learn $^lang"
}.assuming: 'Raku';
say learner :6months; # OUTPUT: «It took me 6 months to learn Raku»
=head2 method count
Defined as:
method count(Code:D: --> Real:D)
Returns the maximum number of positional arguments that may be passed
when calling the code object. For code objects that can accept any
number of positional arguments (that is, they have a slurpy parameter),
C<count> will return C<Inf>. Named parameters do not contribute.
sub argless() { }
sub args($a, $b?) { }
sub slurpy($a, $b, *@c) { }
say &argless.count; # OUTPUT: «0»
say &args.count; # OUTPUT: «2»
say &slurpy.count; # OUTPUT: «Inf»
=head2 method of
Defined as:
method of(Code:D: --> Mu)
Returns the L<return type constraint|/type/Signature#Constraining_return_types>
of the C<Code>:
say -> () --> Int {}.of; # OUTPUT: «(Int)»
=head2 method signature
Defined as:
multi method signature(Code:D: --> Signature:D)
Returns the L<C<Signature>|/type/Signature> object for this code object, which describes
its parameters.
sub a(Int $one, Str $two) {};
say &a.signature; # OUTPUT: «(Int $one, Str $two)»
=head2 method cando
method cando(Capture $c)
Returns a list of candidates that can be called with the given
L<Capture|/type/Capture>. Since C<Code> objects do not have any multiple
dispatch, this either returns a list with the object, or an empty list.
my $single = \'a'; # a single argument Capture
my $plural = \('a', 42); # a two argument Capture
my &block = { say $^a }; # a Block object, that is a subclass of Code, taking one argument
say &block.cando($single); # OUTPUT: «(-> $a { #`(Block|94212856419136) ... })»
say &block.cando($plural); # OUTPUT: «()»
=head2 method Str
Defined as:
multi method Str(Code:D: --> Str:D)
Will output the method name, but also produce a warning. Use C<.raku> or
C<.gist> instead.
sub marine() { }
say ~&marine;
# OUTPUT: «Sub object coerced to string (please use .gist or .raku to do that)marine»
say &marine.Str;
# OUTPUT: «Sub object coerced to string (please use .gist or .raku to do that)marine»
say &marine.raku; # OUTPUT: «sub marine { #`(Sub|94280758332168) ... }»
=head2 method file
Defined as:
method file(Code:D: --> Str:D)
Returns the name of the file in which the code object was declared.
say &infix:<+>.file;
=head2 method line
Defined as
method line(Code:D: --> Int:D)
Returns the line number in the source code at which the code object's
declaration begins.
say &infix:<+>.line;
If the code object was generated automatically (and thus I<not>
declared in the source code), then C<line> returns the line on which
the enclosing scope's declaration begins. For example, when called on
an L<automatically generated accessor method|
/language/objects#Attributes> produced by the C<has $.name>
syntax, C<line> returns the line on which the method's class's
declaration begins.
For example, if you have the following source file:
class Food { # Line 1
has $.ingredients; # Line 2
# Line 3
method eat {}; # Line 4
} # Line 5
Then the C<line> method would give you the following output:
=begin code :preamble<class Food { has $.ingredients; method eat {};}>
say Food.^lookup('eat').line; # OUTPUT: «4»
say Food.^lookup('ingredients').line; # OUTPUT: «1»
=end code
=head2 method is-implementation-detail
method is-implementation-detail(--> False)
Note: this trait has been available in Rakudo compiler starting from 2020.05 release.
Returns C<True> if the code object was marked with C<is implementation-detail> trait,
C<False> otherwise.
=end pod
# vim: expandtab softtabstop=4 shiftwidth=4 ft=perl6