is Code
A Block
is a code object meant for small-scale code reuse. A block is created syntactically by a list of statements enclosed in curly braces. The literal for creating an empty block is {;}
.
Without an explicit signature or placeholder arguments, a block has $_
as a positional argument, which defaults to the outer scope's $_
. Thus it will inherit the topic if there is any.
my = ;say .^name; # OUTPUT: «Block» say ('hello'); # OUTPUT: «HELLO» say .signature; # OUTPUT: «(;; $_? is raw = OUTER::<$_>)»
A block can have a Signature
between ->
or <->
and the block:
my = -> , = 2 ;say (40); # OUTPUT: «42»
If the signature is introduced with <->
, then the parameters are marked as rw
by default:
my = <-> , ;my (, ) = (2, 4);(, );say ; # OUTPUT: «4»
Blocks that aren't of type Routine
(which is a subclass of Block
) are transparent to return
.
sub f()
The last statement is the implicit return value of the block.
say .(); # OUTPUT: «1»
Bare blocks are automatically executed in the order they appear:
say 1; # OUTPUT: «1» say 3; # OUTPUT: «3»
Type Graph §
Routines supplied by class Code §
Block inherits from class Code, which provides the following routines:
(Code) method ACCEPTS §
multi method ACCEPTS(Code: Mu )
Usually calls the code object and passes $topic
as an argument. However, when called on a code object that takes no arguments, the code object is invoked with no arguments and $topic
is dropped. The result of the call is returned.
(Code) method arity §
Defined as:
method arity(Code: --> Int)
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 Signature
do not contribute, nor do named parameters.
sub argless() sub args(, ?) sub slurpy(, , *) say .arity; # OUTPUT: «0» say .arity; # OUTPUT: «1» say .arity; # OUTPUT: «2»
(Code) method assuming §
method assuming(Callable : |primers)
Returns a 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(); # takes only one parameter and as such wont forward $n sub bench(); say .assuming(10000000).; # OUTPUT: «(10000000 7.5508834)»
For a sub with arity greater than one, you can use Whatever
*
for all of the positional parameters that are not "assumed".
sub first-and-last ( , ) my = .assuming( *, 'Smith' ); .( 'Joe' ); # OUTPUT: «Name is Joe Smith»
You can handle any combination of assumed and not assumed positional parameters:
sub longer-names ( , , , ) my = .assuming( *, *, 'Public', * ); .( 'Joe', 'Q.', 'Jr.'); # OUTPUT: «Name is Joe Q. Public Jr.»
Named parameters can be assumed as well:
sub foo .assuming(13, :42foo)(24, :72bar); # OUTPUT: «13 24 42 72»
And you can use .assuming
on all types of Callables, including Methods and Blocks:
# We use a Whatever star for the invocant: my = Str.^lookup('comb').assuming: *, /P \w+/;say comber 'Perl is awesome! Python is great! And PHP is OK too';# OUTPUT: «(Perl Python PHP)» my = .assuming: 'Raku';say learner :6months; # OUTPUT: «It took me 6 months to learn Raku»
(Code) method count §
Defined as:
method count(Code: --> Real)
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), count
will return Inf
. Named parameters do not contribute.
sub argless() sub args(, ?) sub slurpy(, , *) say .count; # OUTPUT: «0» say .count; # OUTPUT: «2» say .count; # OUTPUT: «Inf»
(Code) method of §
Defined as:
method of(Code: --> Mu)
Returns the return type constraint of the Code
:
say -> () --> Int .of; # OUTPUT: «(Int)»
(Code) method signature §
Defined as:
multi method signature(Code: --> Signature)
Returns the Signature
object for this code object, which describes its parameters.
sub a(Int , Str ) ;say .signature; # OUTPUT: «(Int $one, Str $two)»
(Code) method cando §
method cando(Capture )
Returns a list of candidates that can be called with the given Capture. Since Code
objects do not have any multiple dispatch, this either returns a list with the object, or an empty list.
my = \'a'; # a single argument Capture my = \('a', 42); # a two argument Capture my = ; # a Block object, that is a subclass of Code, taking one argument say .cando(); # OUTPUT: «(-> $a { #`(Block|94212856419136) ... })» say .cando(); # OUTPUT: «()»
(Code) method Str §
Defined as:
multi method Str(Code: --> Str)
Will output the method name, but also produce a warning. Use .raku
or .gist
instead.
sub marine() say ~;# OUTPUT: «Sub object coerced to string (please use .gist or .raku to do that)marine» say .Str;# OUTPUT: «Sub object coerced to string (please use .gist or .raku to do that)marine» say .raku; # OUTPUT: «sub marine { #`(Sub|94280758332168) ... }»
(Code) method file §
Defined as:
method file(Code: --> Str)
Returns the name of the file in which the code object was declared.
say :<+>.file; # OUTPUT: «SETTING::src/core.c/Numeric.pm6»
(Code) method line §
Defined as
method line(Code: --> Int)
Returns the line number in the source code at which the code object's declaration begins.
say :<+>.line; # OUTPUT: «208»
If the code object was generated automatically (and thus not declared in the source code), then line
returns the line on which the enclosing scope's declaration begins. For example, when called on an automatically generated accessor method produced by the has $.name
syntax, line
returns the line on which the method's class's declaration begins.
For example, if you have the following source file:
# Line 5
Then the line
method would give you the following output:
say Food.^lookup('eat').line; # OUTPUT: «4» say Food.^lookup('ingredients').line; # OUTPUT: «1»
(Code) method is-implementation-detail §
method is-implementation-detail(--> False)
Note: this method has been available in Rakudo compiler starting from 2020.05 release.
Returns True
if the code object was marked with is implementation-detail
trait, False
otherwise.
Routines supplied by role Callable §
Block inherits from class Code, which does role Callable, which provides the following routines:
(Callable) method CALL-ME §
method CALL-ME(Callable : |arguments)
This method is required for the ( )
postcircumfix operator and the .( )
postcircumfix operator. It's what makes an object actually call-able and needs to be overloaded to let a given object act like a routine. If the object needs to be stored in a &
-sigiled container, it has to implement Callable.
does Callable my = A;say a(); # OUTPUT: «called»
Applying the Callable
role is not a requirement to make an object callable; if a class simply wants to add subroutine-like semantics in a regular scalar container, the submethod CALL-ME
can be used for that.
my = A.new: values => [4,5,6,7];say (2); # OUTPUT: «6»
(Callable) method Capture §
Defined as:
method Capture()
Throws X::Cannot::Capture
.