In Classes and objects§

See primary documentation in context for Private methods.

Just like attributes, methods can also be private. Private methods are declared with a prefixed exclamation mark. They are called with self! followed by the method's name. In the following implementation of a MP3TagData class to extract ID3v1 metadata from an mp3 file, methods parse-data, can-read-format, and trim-nulls are private methods while the remaining ones are public methods:

class MP3TagData {
    has $.filename where { .IO ~~ :e };

    has Str $.title   is built(False);
    has Str $.artist  is built(False);
    has Str $.album   is built(False);
    has Str $.year    is built(False);
    has Str $.comment is built(False);
    has Int $.genre   is built(False);
    has Int $.track   is built(False);
    has Str $.version is built(False);
    has Str $.type    is built(False) = 'ID3';

    submethod TWEAK {
        with $!filename.IO.open(:r, :bin) -> $fh {
            $fh.seek(-128, SeekFromEnd);
            my $tagdata = $fh.read(128);
            self!parse-data: $tagdata;
            $fh.close;
        }
        else {
            warn "Failed to open file."
        }
    }

    method !parse-data($data) {
        if self!can-read-format($data) {
            my $offset = $data.bytes - 128;

            $!title  = self!trim-nulls: $data.subbuf($offset +  3, 30);
            $!artist = self!trim-nulls: $data.subbuf($offset + 33, 30);
            $!album  = self!trim-nulls: $data.subbuf($offset + 63, 30);
            $!year   = self!trim-nulls: $data.subbuf($offset + 93,  4);

            my Int $track-flag = $data.subbuf($offset + 97 + 28, 1).Int;
            $!track            = $data.subbuf($offset + 97 + 29, 1).Int;

            ($!version, $!comment) = $track-flag == 0 && $!track != 0
                ?? ('1.1', self!trim-nulls: $data.subbuf($offset + 97, 28))
                !! ('1.0', self!trim-nulls: $data.subbuf($offset + 97, 30));

            $!genre = $data.subbuf($offset + 97 + 30, 1).Int;
        }
    }

    method !can-read-format(Buf $data --> Bool) {
        self!trim-nulls($data.subbuf(0..2)) eq 'TAG'
    }

    method !trim-nulls(Buf $data --> Str) {
        $data.decode('utf-8').subst(/\x[0000]+/, '')
    }
}

To call a private method of another class, the caller has to be trusted by the callee. A trust relationship is declared with trusts and the class to be trusted must already be declared. Calling a private method of another class requires an instance of that class and the fully qualified name (FQN) of the method. A trust relationship also allows access to private attributes.

class B {...}

class C {
    trusts B;
    has $!hidden = 'invisible';
    method !not-yours () { say 'hidden' }
    method yours-to-use () {
        say $!hidden;
        self!not-yours();
    }
}

class B {
    method i-am-trusted () {
        my C $c.=new;
        $c!C::not-yours();
    }
}

C.new.yours-to-use(); # the context of this call is GLOBAL, and not trusted by C
B.new.i-am-trusted();

Trust relationships are not subject to inheritance. To trust the global namespace, the pseudo package GLOBAL can be used.