Control flow · Classes and OO

method#

Declare a named instance method inside a class block.

method defines a subroutine that expects to be invoked on an object of the enclosing class. It behaves like sub, with two additional guarantees that sub does not give you: the lexical $self is bound to the invocant automatically, and signatures are always on — you write parameters as if use feature 'signatures' were in effect, and $self does not appear in that signature.

method is only valid inside a class declaration. Outside a class block it is a compile-time error.

Note

Experimental feature The class, method, and field keywords are part of the experimental class feature (introduced in Perl 5.38). Enabling it with use feature 'class'; emits a warning in the experimental::class category. The syntax and semantics may still change between Perl releases.

Synopsis#

method NAME BLOCK
method NAME SIGNATURE BLOCK
method NAME : ATTRS BLOCK
method SIGNATURE BLOCK       # anonymous
method BLOCK                 # anonymous

What you get back#

method is a declaration, not an expression, in its named form — it installs the method in the enclosing class’s method table and evaluates to nothing useful at the statement position. The anonymous form returns a code reference that remembers the class context and can be called later with an object invocant.

The body of a method is called with the object as the invocant. The return value of the method is whatever the block returns, following the same context rules as a regular subroutine call.

What method gives you that sub does not#

Four things differ from writing sub inside a class block:

  • $self is pre-declared. A lexical $self is created in the method’s scope and initialised to the invocant. You do not — and should not — shift it off @_.

  • Signatures are always enabled. You can write method greet($name) { ... } without use feature 'signatures'. The $self invocant is consumed before the signature binds, so it never appears in the parameter list.

  • Fields are in scope. Any field variables declared in the enclosing class are visible by their lexical names inside the method body. A plain sub inside a class block does not see fields.

  • It is registered as a method. The method table of the class records the name, which is what the method-resolution machinery looks up for $obj->name(...) dispatch. A plain sub inside the class block is a helper, not a method.

Put the other way: a sub inside a class block is an ordinary package subroutine that happens to live in that package’s namespace. It has no $self, no field visibility, and is not part of the class’s method interface — call it via ClassName::helper(...) if you must, not via an arrow.

Examples#

A minimal class with a method and a field:

use v5.38;
use feature 'class';
no warnings 'experimental::class';

class Greeter {
    field $greeting = "Hello";

    method greet($name) {
        return "$greeting, $name";
    }
}

my $g = Greeter->new;
say $g->greet("world");           # Hello, world

Signature defaults work exactly as they do for sub:

class Greeter {
    field $greeting = "Hello";

    method greet($name = "someone") {
        return "$greeting, $name";
    }
}

say Greeter->new->greet;          # Hello, someone

A method with no parameters still uses the signature form — the empty () is not required, but it is allowed and is the common style when the method takes arguments elsewhere in the class:

class Counter {
    field $n = 0;

    method inc        { $n++ }
    method value ()   { return $n }
}

An anonymous method — useful as a factory or as a callback that needs access to $self and fields:

class AnonMethodFactory {
    method make_printer {
        return method { say "called on $self" };
    }
}

A lexical (private) method declared with my method. Invoke it via the ->& operator, which bypasses method lookup and calls the lexical directly as if it were a method:

class LexicalMethod {
    my method _check ($x, $y) {
        return $x > 0 && $y > 0;
    }

    method process ($x, $y) {
        return unless $self->&_check($x, $y);
        # ...
    }
}

Regular sub inside a class, contrasted with method — the sub is a helper, the method is the public interface:

class Temperature {
    field $celsius;

    sub _c_to_f ($c) { $c * 9 / 5 + 32 }   # helper, no $self, no fields

    method fahrenheit {
        return _c_to_f($celsius);
    }
}

Edge cases#

  • Outside a class block is a compile-time error. method foo { ... } at the top level, or inside a package that is not a class, does not parse. Use sub there.

  • $self is read-only in the sense that you cannot declare another lexical with the same name at the top of the method — it is already in scope. Assigning to $self (e.g. $self = ...) is permitted but rarely useful and does not change the caller’s invocant.

  • @_ is not the argument list you expect. Under the signatures that method enables, @_ inside the body is empty after the signature binds, just as in any signature-using sub. Read parameters from the signature, not @_.

  • Method-resolution order is set by the enclosing class. method itself does not take an MRO option; inheritance and dispatch follow whatever the class declaration configured via :isa and related attributes.

  • method does not participate in prototypes. Methods are invoked through dispatch, not direct symbol-table calls, so prototypes (the :prototype(...) attribute on a sub) have no effect here. Use the signature to constrain the call shape.

  • Attributes. The method NAME : ATTRS BLOCK form accepts attributes the same way sub NAME : ATTRS BLOCK does. The set of useful attributes on methods is still settling with the class feature; consult upstream before relying on custom ones.

  • Anonymous-method return-from-method trap. return method { ... } returns a code reference. method { ... } as the last expression of a method without return is still a code reference, but readers often misread it as a block — prefer explicit return for clarity.

Differences from upstream#

Fully compatible with upstream Perl 5.42.

The class feature — and therefore method — is marked experimental in upstream; pperl inherits that status and the experimental::class warning category.

See also#

  • class — declares the package that method lives in; method only parses inside a class block

  • field — per-instance variables that are visible by name inside every method of the enclosing class

  • sub — declare a regular subroutine; use this for helpers inside a class that do not need $self or field access

  • __CLASS__ — the name of the current class, useful inside methods that need to dispatch back to class-level code

  • return — explicit return from a method body; recommended when the last expression is itself a method { ... } anonymous form

  • my — prefix a method with my to declare a lexical (private) method invoked via ->&