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.