Code object constructed by Whatever-currying
When you wish to control how a method or function interprets any Whatever stars, you may use multi dispatch with
WhateverCode parameters to do so, as in the following example:
multi sub get-val(Cycle , Int )# Define what to do with a stand-alone * as the second argumentmulti sub get-val(Cycle , Whatever )# Define what to do with a * WhateverCode in an expressionmulti sub get-val(Cycle , WhateverCode )my Cycle .= new(:pos(2), :vals(0..^10));say get-val(, 3); # OUTPUT: «3␤»say get-val(, *); # OUTPUT: «2␤»say get-val(, *-1); # OUTPUT: «1␤»
does Callable role, so it's possible to introspect the type of
Callable it contains. Continuing the previous example, we can add a multi that handles a
WhateverCode with two arguments:
# Define what to do with two * in an expressionmulti sub get-val(Cycle , WhateverCode where )say get-val(, * + * div 2); # 2 + 10/2 = 7
Note, though, that subexpressions may impose their own Whatever star rules:
my = (0, 1, 2);say get-val(, ) # 2, because the star belongs to the Array class
This can make the ownership of Whatever stars become confusing rather quickly, so be careful not to overdo it.
You may instead type-constrain using Callable type in order to accept any
sub run-with-rand (Callable ) ;run-with-rand *.say; # OUTPUT: «0.773672071688484␤»run-with-rand ; # OUTPUT: «0.38673179353983␤»run-with-rand sub ; # OUTPUT: «0.0589543603685792␤»
&-sigiled parameter works equally well and is shorter to type:
sub run-with-rand () ;
WhateverCode inherits from class Code, which provides the following routines:
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.
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␤»
method assuming(Callable : |primers)
Callable that implements the same behaviour 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 $nsub bench();say .assuming(10000000).; # OUTPUT: «(10000000 7.5508834)␤»
For a sub with arity greater than one, you can use
* 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␤»
# 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: 'Perl 6';say learner :6months; # OUTPUT: «It took me 6 months to learn Perl 6␤»
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␤»
multi method signature(Code: --> Signature)
Signature object for this code object, which describes its parameters.
sub a(Int , Str ) ;say .signature; # OUTPUT: «(Int $one, Str $two)␤»
multi method Str(Code: --> Str)
Will produce a warning. Use
sub marine()say ~; # OUTPUT: «marine␤»say .Str; # OUTPUT: «marine␤»
method file(Code: --> Str)
Returns the name of the file in which the code object was declared.
method line(Code: --> Int)
Returns the line number in which the code object was declared.
method CALL-ME(Callable : |arguments)
This method is required for postfix:«( )» and postfix:«.( )». 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, is has to implement Callable.
does Callablemy = A;say a(); # OUTPUT: «called␤»