Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re: Proper way to call subclass methods?

by Tanktalus (Canon)
on Mar 08, 2016 at 16:07 UTC ( #1157098=note: print w/replies, xml ) Need Help??


in reply to Proper way to call subclass methods?

I think you have your question backwards. You really want to call superclass methods.

You're conflating two OO idioms - inheritance (what you're derived from - in perl, we set @ISA, but better is base, and better yet is parent, and, depending on who you ask, there are better options available in Moose, Moo, and others), and composition (also known as "Has-A" - as in, FFMech Has A WWW::Mechanize::Firefox object). Don't do both for the same type.

You need to pick one. In general, if you want to expose nearly everything, maybe with a few tweaks, inheritance is easier. To set that up, you just use parent 'WWW::Mechanize::Firefox'; and you're mostly done. In your case, I see you have some extra defaults, so you can pass them on in your overridden new:

sub new { my ($class, %args) = @_; my $self = $class->SUPER::new(launch => 'firefox', activate => 1, %a +rgs); $self->{_window_id} = FindWindowLike('Mozilla Firefox); ClickWindow($self->{_window_id}); if ($self->title =~ /Restore Session/i) { $self->click( { selector => '#errorCancel' } ); } return $self; }
And you call this as my $ffm = FFMech->new(...);. I leave it as an exercise for the reader to extend this out to the EventRepository subclass - it's far simpler.

You'll notice that this no longer needs to call $self->{_mech} for getting to the mech object - because $self @ISA mech object, fully initialised!

For composition, you don't want to set up the @ISA relationship, so you don't set @ISA, call use parent or base or anything like that. Just use WWW::Mechanize::Firefox; to ensure it's loaded, and then you can create it in your constructor. However, then you have to redirect the interfaces you want to expose, e.g.:

sub get { my $self = shift; $self->{_mech}->get(@_); }
This can get annoying, so you could generate these functions:
for my $func (qw(get click ...)) { no strict 'refs'; *$func = sub { my $self = shift; $self->{_mech}->$func(@_); }; }
You can reduce the scope of that no strict 'refs' bit even more, I'm just being lazy and not testing stuff here, because there's a better way. You remember how I mentioned that there are better options than parent? Moose (and maybe Moo - I haven't used Moo) allows you to say you have a member variable which "handles" certain methods, and Moose will generate the redirection methods for you:
use Moose; has _mech => ( is => 'rw', handles => [ qw(get click ...) ] );
Mind you, this will take a bit more work to set up so that you could make that _mech readonly ('ro') and such, and this becomes a dark, deep rabbit hole you can chase forever :) but it will forever transform the way you do OO in perl. Personally, a project has to cross a fuzzy threshold to warrant using Moose, but when it does, then I use it. The downside to this heuristic is that if a project starts out small and then scope creep happens, it can cross that threshold and switching to Moose becomes a bit extra work than if I know it'll be big from the outset and reach for Moose from the beginning.

Replies are listed 'Best First'.
Re^2: Proper way to call subclass methods?
by nysus (Parson) on Mar 08, 2016 at 17:12 UTC

    OK, I will noodle through this. Thanks. I'm using Daman Conway's old book from 2000 to get up to speed. I guess it's a bit obsolete because it doesn't mention "parent" and "base". Are there any more recent Perl OO books I should be looking at?

    $PM = "Perl Monk's";
    $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon";
    $nysus = $PM . $MCF;
    Click here if you love Perl Monks

      16 years is a long time in IT/CS. Conway's book is still worth absorbing though. This has some good stuff. I reach for Moo much faster than Moose but opinions differ and some monks think both are overkill/foolish. :P

        I'm thinking I should learn "old school" OO Perl for now before taking on Moo and Moose. Is that a good idea?

        $PM = "Perl Monk's";
        $MCF = "Most Clueless Friar Abbot Bishop Pontiff Deacon";
        $nysus = $PM . $MCF;
        Click here if you love Perl Monks

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1157098]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (3)
As of 2021-09-18 18:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?