Perl-Apollo/Corinna

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)
Ovid commented

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.