The solution which consist in calling the "can" method works

It sounds like you have found a working solution, but in case you still wonder why your original code didn't work (and for the sake of others who don't know), I'll reply to your code as originally posted.

The main problem I see is that you're trying to take a reference to a method. The thing is, a method is just a plain subroutine that has been called against an object. It doesn't become a method until a certain action is taken. You can't directly take a reference to that action; you can only take a reference to the subroutine.

When you take a reference to a subroutine, you are taking a reference to that exact subroutine. It is unambiguous. It does not travel the inheritance tree looking for parent packages with subroutines named the same thing. That doesn't even make sense all the time, as subroutine references can be anonymous, in which case they neither belong to a package nor have a name.

So what you need to do is encapsulate the action in a reference. The way to encapsulate action is with subroutines, so you have to create another subroutine that calls the target as a method. This may sound like a hassle, but Perl makes it pretty simple:

$self->addTab(sub { $self->WatchLog });

Now, when you want to execute that reference, you don't need to do any additional work to call it as a method. It already encapsulates its own method-calling behavior, so you can simply execute the coderef:

foreach my $code (@{$self->{CODETAB}}){ $code->(); }

This also gives you the flexibility to create code tabs that aren't methods. I'm not sure if that's a flexibility you really want, but it's definitely something I would consider.

As for the can solution, I imagine you are doing something along the lines of:

$self->addTab($self->can("WatchLog"));

This avoids your problem by traversing the inheritance tree to find the subroutine reference. It still takes a direct reference to the subroutine, but this time it's the correct subroutine, and you can fudge the method-calling semantics as you did before.

Update: typo, s/corrent/correct/


In reply to Re: I'm in trouble with Perl's OO programming by revdiablo
in thread I'm in trouble with Perl's OO programming by cybergeek

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.