-
Notifications
You must be signed in to change notification settings - Fork 19
Classes
Please see the main page of the repo for the actual RFC. As it states there:
Anything in the Wiki should be considered "rough drafts."
Click here to provide feedback.
Note: this is very rough and written in a pre-coffee morning haze while enjoying the luxury of coronavirus (which I don't have) confinement in southern France. Be gentle!
Based off of our grammar, declaring a Corinna class can be as simple as:
class Foo {}
my $foo = Foo->new;
Of course, that object does nothing and is relatively useless, but you get the idea.
A class is:
- A declaration of a namespace (required)
- A version (optional)
- Classes it inherits from (optional)
- Roles it consumes (optional)
- Slots it has (optional)
- Methods it provides (optional)
You can read the grammar (that's more accurate), but basically, it looks like this:
class CLASSNAME VERSION isa LIST,OF,PARENTS does LIST,OF,ROLES {
has ...
has ...
method foo (...) {...}
method foo (...) {...}
}
So, nothing too radical. A Customer
class which inherits from Person
and implements Serliazable::JSON
might look like this:
class Customer v1.31.0 isa Person does Serializable::JSON v0.03.2 {
use DBI;
has $customer_id :reader :builder;
has $dbh = DBI->connect(...);
method _build_customer_id {
$customer_id = $dbh->selectcol_arrayref(...)->[0];
}
}
We are considering allowing a "descriptor" before the class keyword. Currently, the only descriptor is abstract
and that says "this class is abstract, must be inherited from, and we'll blow up and ruin your day if you try to instantiate it, so don't do that."
In the class declaration (the first line), the every namespace listed is allowed to have a version number after it. For the class declaration, this is the version of the class. For the parents or roles, this is the minimum version of the class which is required.
Versions in Corinna are defined as VERSION ::= 'v' DIGIT {DIGIT} '.' DIGIT {DIGIT} '.' DIGIT {DIGIT}
. This raises some questions.
- What if we inherit from a non-Corinna class which uses a different version scheme?
- Same question for roles if we allow consumption of non-Corinna roles.
- How do we pin an exact version?
- How do we omit unwanted versions?
- Do we care about module authority?
A single version scheme is highly desirable and I believe that my version scheme, as presented, is possibly too limited.
Classes in Corinna have the following behaviors:
- Inherits by default from
UNIVERSAL::Corinna
- Cannot inherit from non-Corinna classes
- Use C3 method resolution
- Allows multiple inheritance (reluctantly)
Note: originally we wrote that Corinna should be allowed to inherit from non-Corinna classes. However, this caused so many design problems that it's probably a very bad idea. Instead, if you want to fake inheritance, use an attribute and delegate (this syntax:
has $file :new :isa(FileName);
has $parser :handles(get_token, get_tag, peek) = HTML::TokeParser::Simple->new($file);
The Corinna base class. Moved to UNIVERSAL::Corinna.
Corinna—Bringing Modern OO to Perl