class Routine

Code object with its own lexical scope and return handling
class Routine is Block { }

A Routine is a code object meant for units of code larger than Block. Routine is the common superclass for Sub (and therefore operators) and Method, the two primary code objects for code reuse, as well as Macro and Submethod.

Routines serve as a scope limiter for return (i.e. a return returns from the innermost outer Routine).

The routine level is also the one at which multiness (multi subs and multi methods) are handled. Subroutines can also be declared anon. See the documentation on the anon declarator for more information.

Routines are the lowest objects in the Code hierarchy that can introspect through the &?ROUTINE variable, which is defined automatically, and contains the corresponding Routine object.

class Foo {
    submethod bar { &?ROUTINE.^name }
};
say Foo.bar; # OUTPUT: Ā«Submethodā¤Ā»

Methods

method name

method name(Routine:D: --> Str:D)

Returns the name of the sub or method.

method package

method package(Routine:D:)

Returns the package in which the routine is defined.

method multi

method multi(Routine:D: --> Bool:D)

Returns True if the routine is a multi sub or method. Note that the name of a multi sub refers to its proto and this method would return false if called on it. It needs to be called on the candidates themselves:

multi foo ($, $) {};
    say &foo.multi;             # OUTPUT: Ā«Falseā¤Ā»
    say &foo.candidatesĀ».multi; # OUTPUT: Ā«(True)ā¤Ā»

method candidates

method candidates(Routine:D: --> Positional:D)

Returns a list of multi candidates, or a one-element list with itself if it's not a multi

method cando

method cando(Capture $c)

Returns a possibly-empty list of candidates that can be called with the given Capture, ordered by narrowest candidate first. For methods, the first element of the Capture needs to be the invocant:

.signature.say for "foo".^can("comb")[0].cando: \(Cool, "o");
    # OUTPUT: Ā«(Cool $: Str $matcher, $limit = Inf, *%_)ā¤Ā»

method wrap

method wrap(Routine:D: &wrapper)

Wraps (i.e. in-place modifies) the routine. That means a call to this routine first calls &wrapper, which then can (but doesn't have to) call the original routine with the callsame, callwith, nextsame and nextwith dispatchers. The return value from the routine is also the return value from the wrapper.

wrap returns an instance of a private class called Routine::WrapHandle, which you can pass to unwrap to restore the original routine.

method unwrap

method unwrap($wraphandle)

Restores the original routine after it has been wrapped with wrap. While the signature allows any type to be passed, only the Routine::WrapHandle type returned from wrap can usefully be.

method is-wrapped

method is-wrapped()

Returns True or False, depending on the whether or not the Routine is wrapped.

method yada

method yada(Routine:D: --> Bool:D)

Returns True if the routine is a stub

say (sub f() { ... }).yada;      # OUTPUT: Ā«Trueā¤Ā»
    say (sub g() { 1;  }).yada;      # OUTPUT: Ā«Falseā¤Ā»

trait is cached

multi trait_mod:<is>(Routine $r, :$cached!)

Causes the return value of a routine to be stored, so that when subsequent calls with the same list of arguments are made, the stored value can be returned immediately instead of re-running the routine.[1]

Useful when storing and returning the computed value is much faster than re-computing it every time, and when the time saved trumps the cost of the use of more memory.

Even if the arguments passed to the routine are "reference types" (such as objects or arrays), then for the purpose of caching they will only be compared based on their contents. Thus the second invocation will hit the cache in this case:

say foo( [1, 2, 3] );   # runs foo
say foo( [1, 2, 3] );   # doesn't run foo, uses cached value

Since it's still at the experimental stage, you will have to insert the use experimental :cached; statement in any module or script that uses it.

use experimental :cached;

sub nth-prime(Int:D $x where * > 0) is cached {
    say "Calculating {$x}th prime";
    return (2..*).grep(*.is-prime)[$x - 1];
}

say nth-prime(43);
say nth-prime(43);
say nth-prime(43);

produces this output:

Calculating 43th prime
191
191
191

Note: This feature is not thread-safe.

trait is pure

multi trait_mod:<is>(Routine $r, :$pure!)

Marks a subroutine as pure, that is, it asserts that for the same input, it will always produce the same output without any additional side effects.

The is pure trait is a promise by the programmer to the compiler that it can constant-fold calls to such functions when the arguments are known at compile time.

sub syllables() is pure {
        say "Generating syllables";
        my @vowels = <a e i o u>;
        return  @vowels.append: <k m n sh d r t y> X~ @vowels;
    }

You can mark function as pure even if they throw exceptions in edge cases or if they modify temporary objects; hence the is pure trait can cover cases that the compiler cannot deduce on its own. On the other hand, you might not want to constant-fold functions that produce a large return value (such as the string or list repetition operators, infix x and xx) even if they are pure, to avoid large precompilation files.

To see it an action with a particular compiler you can try this example:

BEGIN { say ā€˜Beginā€™ }
say ā€˜Startā€™;
say (^100).map: { syllables().pick(4).join("") };
# Example output:
# Begin
# Generating syllables
# Start
# (matiroi yeterani shoriyuru...

Essentially this allows the compiler to perform some operations at compile time. The benefits of constant-folding may include better performance, especially in cases when the folded code is precompiled.

In addition, using a pure function or operator in sink context (that is, where the result is discarded) may lead to a warning. The code

sub double($x) is pure { 2 * $x }; double(21); say "anything"; # WARNING: Ā«Useless use of "double(21)" in expression "double(21)" in sink context (line 2)Ā»

If you want to apply this trait to a multi, you need to apply it to the proto; it will not work otherwise, at least in versions 2018.08 and below.

trait is rw

multi trait_mod:<is>(Routine $r, :$rw!)

When a routine is modified with this trait, its return value will be writable. This is useful when returning variables or writable elements of hashes or arrays, for example:

sub walk(\thing, *@keys) is rw {
    my $current := thing;
    for @keys -> $k {
        if $k ~~ Int {
            $current := $current[$k];
        }
        else {
            $current := $current{$k};
        }
    }
    $current;
}

my %hash;
walk(%hash, 'some', 'key', 1, 2) = 'autovivified';

say %hash.raku;

produces

("some" => {"key" => [Any, [Any, Any, "autovivified"]]}).hash

Note that return marks return values as read only; if you need an early exit from an is rw routine, you have to use return-rw|Reference,return-rw instead.

trait is export

multi trait_mod:<is>(Routine $r, :$export!)

Marks a routine as exported to the rest of the world

module Foo {
    sub double($x) is export {
        2 * $x
    }
}

import Foo;         # makes sub double available
say double 21;      # 42

From inside another file you'd say use Foo; to load a module and import the exported functions.

See Exporting and Selective Importing Modules for more details.

trait is DEPRECATED

multi trait_mod:<is>(Routine:D $r, :$DEPRECATED!)

Marks a Routine as deprecated; that is, it should no longer be used going forward, and will eventually be removed. An optional message specifying the replacement functionality can be specified

By having both the original (deprecated) and new Routine available simultaneously, you can avoid a breaking change in a single release, by allowing users time and instructions on how to update their code. Remove the deprecated version only after at least one release that includes both the warning and the new Routine.

This code

sub f() is DEPRECATED('the literal 42') { 42 }
say f();

produces this output:

42
Saw 1 occurrence of deprecated code.
================================================================================
Sub f (from GLOBAL) seen at:
  deprecated.raku, line 2
Please use the literal 42 instead.
--------------------------------------------------------------------------------
Please contact the author to have these occurrences of deprecated code
adapted, so that this message will disappear!

trait is hidden-from-backtrace

multi trait_mod:<is>(Routine:D, :$hidden-from-backtrace!)

Hides a routine from showing up in a default backtrace. For example

sub inner { die "OH NOEZ" };
sub outer { inner() };
outer();

produces the error message and backtrace

OH NOEZ
  in sub inner at bt.raku:1
  in sub outer at bt.raku:2
  in block <unit> at bt.raku:3

but if inner is marked with hidden-from-backtrace

sub inner is hidden-from-backtrace { die "OH NOEZ" };
sub outer { inner() };
outer();

the error backtrace does not show it:

OH NOEZ
  in sub outer at bt.raku:2
  in block <unit> at bt.raku:3

trait is default

multi trait_mod:<is>(Routine:D $r, :$default!)

There is a special trait for Routines called is default. This trait is designed as a way to disambiguate multi calls that would normally throw an error because the compiler would not know which one to use. This means that given the following two Routines, the one with the is default trait will be called.

multi f() is default { say "Hello there" }
    multi f() { say "Hello friend" }
    f();   # OUTPUT: Ā«"Hello there"ā¤Ā»

The is default trait can become very useful for debugging and other uses but keep in mind that it will only resolve an ambiguous dispatch between two Routines of the same precedence. If one of the Routines is narrower than another, then that one will be called. For example:

multi f() is default { say "Hello there" }
multi f(:$greet) { say "Hello " ~ $greet }
f();   # "Use of uninitialized value $greet..."

In this example, the multi without is default was called because it was actually narrower than the Sub with it.

trait is raw

multi trait_mod:<is>(Routine:D $r, :$raw!)

Gives total access to the data structure returned by the routine.

my @zipi = <zape zapatilla>;
sub Ć¾or() is raw {
    return @zipi
};
Ć¾or()[1] = 'pantuflo';
say @zipi;  # OUTPUT: Ā«[zape pantuflo]ā¤Ā»

trait is test-assertion

multi trait_mod:<is>(Routine:D, :$test-assertion!)

Declares that a routine generates test output (aka TAP). When failures are reported, the calling routine's location is used instead of this routine. For example:

use Test;
sub foo-test($value) is test-assertion {
    is $value, 42, "is the value 42?";
}
foo-test(666);    # <-- error is reported on this line

[1]This is still in experimental stage. Please check the corresponding section in the experimental features document

See Also

class int

Native integer

class Allomorph

Dual value number and string

class Any

Thing/object

class AST

Abstract representation of a piece of source code

class atomicint

Integer (native storage at the platform's atomic operation size)

class Block

Code object with its own lexical scope

class CallFrame

Captures the current frame state

class Code

Code object

class Collation

Encapsulates instructions about how strings should be sorted

class Compiler

Information related to the compiler that is being used

class Complex

Complex number

class ComplexStr

Dual value complex number and string

class Cool

Object that can be treated as both a string and number

class CurrentThreadScheduler

Scheduler that synchronously executes code on the current thread

class Date

Calendar date

class DateTime

Calendar date with time

class Distribution::Hash

Distribution::Hash

class Distribution::Locally

Distribution::Locally

class Distribution::Path

Distribution::Path

class Distribution::Resource

Every one of the resources installed with a distribution

class Duration

Length of time

class Encoding::Registry

Management of available encodings

class FatRat

Rational number (arbitrary-precision)

class ForeignCode

Rakudo-specific class that wraps around code in other languages (generally NQP)

class Format

Convert values to a string given a format specification

class Formatter

Produce Callable for given format specification

class HyperSeq

An object for performing batches of work in parallel with ordered output

class HyperWhatever

Placeholder for multiple unspecified values/arguments

class Instant

Specific moment in time

class Int

Integer (arbitrary-precision)

class IntStr

Dual value integer and string

class Junction

Logical superposition of values

class Label

Tagged location in the source code

class Lock::Async

A non-blocking, non-re-entrant, mutual exclusion lock

class Macro

Compile-time routine

class Method

Member function

class Mu

The root of the Raku type hierarchy.

class Nil

Absence of a value or a benign failure

class Num

Floating-point number

role Numeric

Number or object that can act as a number

class NumStr

Dual value floating-point number and string

class ObjAt

Unique identification for an object

class Parameter

Element of a Signature

class Perl

Perl related information

class Proxy

Item container with custom storage and retrieval

class RaceSeq

Performs batches of work in parallel without respecting original order.

class Raku

Raku related information

package RakuAST

Namespace for holding RakuAST related classes

class RakuAST::Doc::Block

Contains the information of a RakuDoc block

class RakuAST::Doc::Declarator

Contains the declarator docs of a RakuAST object

class RakuAST::Doc::Markup

Contains the information about RakuDoc markup

class RakuAST::Doc::Paragraph

Contains the information about a RakuDoc paragraph

class Rat

Rational number (limited-precision)

class RatStr

Dual value rational number and string

class Routine::WrapHandle

Holds all information needed to unwrap a wrapped routine.

class Scalar

A mostly transparent container used for indirections

class Signature

Parameter list pattern

class Str

String of characters

class StrDistance

Contains the result of a string transformation.

class Sub

Subroutine

class Submethod

Member function that is not inherited by subclasses

class Telemetry

Collect performance state for analysis

class Telemetry::Instrument::Thread

Instrument for collecting Thread data

class Telemetry::Instrument::ThreadPool

Instrument for collecting ThreadPoolScheduler data

class Telemetry::Instrument::Usage

Instrument for collecting getrusage data

class Telemetry::Period

Performance data over a period

class Telemetry::Sampler

Telemetry instrument pod

Subset UInt

Unsigned integer (arbitrary-precision)

class ValueObjAt

Unique identification for value types

class Variable

Object representation of a variable for use in traits

class Version

Module version descriptor

class Whatever

Placeholder for the value of an unspecified argument

class WhateverCode

Code object constructed by Whatever-priming

The Camelia image is copyright 2009 by Larry Wall. "Raku" is trademark of the Yet Another Society. All rights reserved.