Skip to content

Latest commit

 

History

History
150 lines (116 loc) · 4.86 KB

methods.md

File metadata and controls

150 lines (116 loc) · 4.86 KB

Prev: Fields
Next: Roles


Section 7: Methods

This file is automatically generated. If you wish to submit a PR, do not edit this file directly. Please edit templates/rfc/methods.md instead. Use bin/generate_rfc.pl to regenerate the RFCs.


7.1 Overview

Corinna offers class methods and instance methods. You must also specify if they override a parent method.

7.2 Instance Methods

Instance methods are defined via method $identifier (@args) { ... }. They automatically have immutable $class and $self variables injected into them. $class contains the name of the class from which this method was called. $self is an instance of the current class.

method name () {
    return defined $title ? "$title $name" : $name;
}

Instance methods can access both class data and instance data and call both instance and class methods.

7.3 Class Methods

Class methods are defined via method $identifier :common (@args) { ... }. They automatically have an immutable $class variable injected into them. This contains the name of the class from which this method was called.

method foo :common () {
    say "We were called via the $class class";
}

Class methods cannot call instance methods (since they have no $self) and referencing instance data in a class method should be a compile-time error. Ths includes trying to reference $self in a class method.

7.4 Overridden Methods

If a method in the current class overrides a method in a parent class, a warning will be issued. To suppress that warning, use :overrides.

method name :overrides () {
    ...
}

Note that instance methods can only override instance methods and class methods can only override class methods.

7.5 Abstract Methods

Abstract methods are declared as forward declarations. That is, methods without a method body and without a signature.

method foo;
method bar :common;

They have two uses. Any class with an abstract method must declare itself as abstract. Failure to do so would be a compile-time failure.

Abstract methods declared in roles are "required" methods that must be implemented by the consuming class or by other roles consumed at the same time.

Important abstract methods must not be listed with arguments. These are a syntax errors:

method foo ();
method bar ($baz);

7.5.1 Checking Abstract Methods

When compiling code containing abstract methods, the check to see if the method is overridden it should be compile time for a class and composition time for a role. You should be able to compile an abstract class itself with a standard perl -c check, but any class which inherits from the abstract class and doesn't override the methods would either need to be declared abstract or have a compile-time failure.

7.6 Private Methods

Private methods are declared with the private keyword:

method foo :private () {...}
method bar :private :common () {...}

Private methods can only be called from methods defined in the same namespace and file at compile time.

  • Private methods are not inherited
  • If a class or role has a :private method with the name matching the name of the method being called, the dispatch is to that method.
  • Even if a parent class has a public or private method with the same signature, the methods in a class will call its private method, not the inherited one
  • Roles and classes cannot call each other's private methods

Note that this means:

  • Roles cannot require private methods
  • A role's private methods can never conflict with another role or class's private methods
  • You cannot use :overrides and :private on the same method

7.6.1 Private Methods in Roles

There is nothing special about private methods in roles, but they are not flattened into the consuming class and cannot conflict with class methods. Private methods are bound to the namespace in which they are declared. This gives us great encapsulation, but does it require the method be bound at compile-time rather than runtime? If so, does Perl even support that? Or do we need to do a runtime check every time?

Thus:

role SomeRole {
    method role_method () { $self->do_it }
    method do_it :private () { say "SomeRole" }
}
class SomeClass :does(SomeRole) {
    method class_method () { $self->do_it }
    method do_it :private () { say "SomeClass" }
}
my $object = SomeClass->new;
say $object->class_method; # prints "SomeClass"
say $object->role_method;  # prints "SomeRole"

The above do_it methods do not conflict because it's not provided by the role. It's strictly internal. Further, it cannot be aliased, excluded, or renamed by the consumer. This gives role authors the ability to write a role and have fine-grained control over its behavior.


Prev: Fields
Next: Roles