36
loading...
This website collects cookies to deliver better user experience
override
keyword in Perl’s Moose object system is a nice bit of code-as-documentation since it explicitly states that a given method overrides from its superclass. It also has a super
keyword that can be used inside an override
, calling “the next most appropriate superclass method with the same arguments as the original method.”SUPER::
pseudo-package; it is really your choice.” So when should you use one and not the other? I decided to find out.package Local::MyClass;
use Moose;
sub my_method {
return blessed $_[0];
}
__PACKAGE__ ->meta->make_immutable();
1;
override
keyword and one with a plain sub
:package Local::MyClass::MyChildOverride;
use Moose;
extends 'Local::MyClass';
override my_method => sub {
my $self = shift;
return 'child ' . super;
};
__PACKAGE__ ->meta->make_immutable();
1;
package Local::MyClass::MyChildPlain;
use Moose;
extends 'Local::MyClass';
sub my_method {
my $self = shift;
return 'child ' . $self->SUPER::my_method();
}
__PACKAGE__ ->meta->make_immutable();
1;
$ perl -Ilib -MLocal::MyClass::MyChildPlain \
-MLocal::MyClass::MyChildOverride \
-E '$PREFIX = "Local::MyClass::MyChild";
for ( qw(Plain Override) ) {
$object = "$PREFIX$_"->new();
say $object->my_method()
}'
child Local::MyClass::MyChildPlain
child Local::MyClass::MyChildOverride
package Local::MyClassNoMethod;
use Moose;
__PACKAGE__ ->meta->make_immutable();
1;
use
ing the offending subclass during the BEGIN
phase:$ perl -Ilib -MLocal::MyClassNoMethod::MyChildOverride \
-E ''
You cannot override 'my_method' because it has no super method at /Users/mgardner/.plenv/versions/5.34.0/lib/perl5/site_perl/5.34.0/darwin-2level/Moose/Exporter.pm line 419
Moose::override('my_method', 'CODE(0x7fe5cb811a88)') called at lib/Local/MyClassNoMethod/MyChildOverride.pm line 9
require Local/MyClassNoMethod/MyChildOverride.pm at -e line 0
main::BEGIN at lib/Local/MyClassNoMethod/MyChildOverride.pm line 0
eval {...} at lib/Local/MyClassNoMethod/MyChildOverride.pm line 0
Compilation failed in require.
BEGIN failed--compilation aborted.
SUPER::
pseudo-package that things blow up at runtime:$ perl -Ilib -MLocal::MyClassNoMethod::MyChildPlain \
-E '$obj = Local::MyClassNoMethod::MyChildPlain->new();
$obj->my_method()'
Can't locate object method "my_method" via package "Local::MyClassNoMethod::MyChildPlain" at lib/Local/MyClassNoMethod/MyChildPlain.pm line 8.
perl -c
will happily compile all these classes and subclasses without a peep:$ find . -name '*.pm' -exec perl -c {} \;
./lib/Local/MyClass/MyChildPlain.pm syntax OK
./lib/Local/MyClass/MyChildOverride.pm syntax OK
./lib/Local/MyClassNoMethod/MyChildPlain.pm syntax OK
./lib/Local/MyClassNoMethod/MyChildOverride.pm syntax OK
./lib/Local/MyClass.pm syntax OK
./lib/Local/MyClassNoMethod.pm syntax OK
override
is a good way of describing your intent with a subclass, and it will catch you out if you try to use it without a corresponding method in a superclass. It is a non-standard keyword though , so syntax-highlighting editors and code analysis tools won’t recognize it unless taught. Further, if your subclass method doesn’t call the same method in a superclass you could eventually get away with removing the latter if you use a plain sub
.override
suitable for your Moose projects, or are you satisfied with plain sub
? Let me know in the comments.