-
Notifications
You must be signed in to change notification settings - Fork 19
Slot Semantics
After a bit of discussion on #cor, it turns out that having slot declarations being lexical and using the slot identifier name as the public name is causing some issues.
Slots are private (which works in isolation), but NEW constructor needs to be able to "see" the slots in all of the lexical scopes if they have :new or :new(optional) (unless NEW is implicitly in every class).
But what do we do for this?
class Parent {
has $x :isa(Int) :new;
}
class Child isa Parent {
has $x :isa(Str) :new;
}
In the above, we have a few issues.
First, if I call my $o = Child->new( x => 'bob')
, what does the Child $x
get? Internally, we have to build classes from the bottom to the top of the
heirachy and the parent would get the child's type of the slot.
We also have similar issues with roles. There other issues, but that's a clear one that exposes all of the issues.
It seems like the problem here is that the variable holding the slot and the external name of the slot are tightly coupled.
The proposal to fix this is to decouple the name of the variable containing
the slot and the attribute for the slot (similar to init_arg
in Moo/se, but
not quite the same).
I think this can be done with a new attribute called :name($identifier)
.
class Parent {
# without a :name(...) attribute, the name is 'x'
has $x :isa(Int) :new;
}
class Child isa Parent {
has $x :isa(Str) :name(some_x) :new;
}
Now in the above, to construct it:
my $object = Child->new(
x => 42,
some_x => 'DNA',
);
This means that for roles, we'd do the same thing. The slot variable would be lexically scoped, but the slot name would determine the name by which we read/write/construct the slot data.
A child could override the parent slot names, but role slot names would require the standard role exclusion and aliasing behaviors.
Corinna—Bringing Modern OO to Perl