John M. Dlugosz has asked for the wisdom of the Perl Monks concerning the following question:

Consider the following code using "classic" Perl 5 Objects, as shown in perlboot.
use 5.10.1; use strict; use warnings; { package Base; sub new { my $class= shift; return bless ({}, $class); } sub baz { my ($self,$x)= @_; say "Baz called: " . $self . " ($x)"; } } # end of class { package Derived; our @ISA = 'Base'; } # end of class say "I'm running."; my $d= Derived->new; $d->baz(1); Base->baz(2); Derived->baz(3);
As I've come to expect, the arrow syntax on class names will find inherited functions. The function defined in the base class is found and passed the derived class name as the first argument.

However, trying some things with Moose:

use 5.10.1; use MooseX::Declare; class Base { sub baz { my ($self,$x)= @_; say "Baz called: " . $self . " ($x)"; } } #end of Base class Derived { method foo (Num $x) { say "Foo called: " . ref($self) . " ($x)"; } sub bar { my ($self,$x)= @_; say "Bar called: " . ref($self) . " ($x)"; } } #end of Derived say "I'm running."; my $d= Derived->new; $d->foo (1); #Derived->foo(2); #cannot call as static # this one is allowed. $d->bar (1); Derived->bar(2); $d->baz(1); Base->baz(2); Derived->baz(3); # does not find it!
In particular, the last line, Derived->baz(3), shows that it will not find inherited subs called on the Class (not an instance).

Why not?

And how can it it not? If it uses the normal Perl mechanism to locate subs on instances, why doesn't it work on class names too?

Confused as ever,
—John

Replies are listed 'Best First'.
Re: Moose and class methods
by chromatic (Archbishop) on Apr 30, 2011 at 17:54 UTC

    It's a simple typo:

    class Derived extends Base { ... }
      Oops!

      I had banged on that code quite a bit. Must have lost it at some point and forgot.

      As expected, it works fine when I fixed the Base.

Re: Moose and class methods
by stvn (Monsignor) on May 01, 2011 at 02:02 UTC

    What chromatic said.

    But also, don't use MooseX::Declare unless you are willing to take on the extra burden of its (poor) error handling and extra startup/runtime overhead (much more so then vanilla Moose). MooseX::Declare is (mostly) stable, but really should only be used by people who find more value in having the syntactic sugar over performance and sane error reporting (read: I don't use it and don't allow it to be used for $work code).

    -stvn
      No problem. I'm not using it for my main code, but wanted to try it. I thought it was good for cramming several classes into one file because of the declarative region idea.
Re: Moose and class methods
by Anonymous Monk on Apr 30, 2011 at 12:51 UTC