RFC/Classes: if a method :overrides its base class method, it should allow a different signature
Closed this issue · 1 comments
The example method in the "Inheritance" section contains a line my $name = self->next::method
. This leaves unclear whether it means my $name = self->next::method()
(because the name
method takes no parameters) or whether it means my $name = self->next::method(@_)
, i.e. the current parameter list is passed unchanged.
If it is the first alternative, just adding the parens will make that clear.
If it is the second, then this impedes an use case for inheritance where the derived class is actually a special case of its parent class. For example, a cube is a cuboid, or in Corinna speek, class Cube :isa(Cuboid)
. However, a cube only takes one parameter on construction and also on methods. A resize
method for a cuboid takes three parameters, the equivalent method for a cube takes only one.
The example below shows how I'd like it to work (it also shows some known deficiencies which we currently have with inheritance: I have to define defaults, and to expose writers for all slots which might be special-cased by subclasses).
class Cuboid {
slot $length :param :reader;
slot $width :param :reader :writer = 0;
slot $height :param :reader :writer = 0;
method resize ($new_length, $new_width, $new_height) {
$length = $new_length;
$width = $new_width;
$height = $new_height;
}
method dump {
say "$class ($length,$width,$height)";
}
};
class Cube :isa(Cuboid) {
ADJUST {
$self->set_width($self->length);
$self->set_height($self->length);
}
method resize :overrides ($new_length) {
$self->SUPER::resize($new_length,$new_length,$new_length);
}
};
my $cube = Cube->new(length => 1);
$cube->dump; # Cube (1,1,1)
$cube->resize(2);
$cube->dump; # Cube (2,2,2)
It meant my $name = $self->next::method()
. It wasn't intended to automagically pass through parameter lists. I've added the parentheses to the examples.