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.
Corinna offers class methods and instance methods. You must also specify if they override a parent method.
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.
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.
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.
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);
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.
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
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.