On 9/29/07, Linda W <[EMAIL PROTECTED]> wrote:
> I've somehow broken Perl's OO mechanism.
> When calling through a blessed reference, it is not finding
> (nor, apparently, searching) methods in "Base" or ancestral
> classes....
>
> Not if this is "a" or "the" right forum or which would be better
> if this isn't a right place.
> I tried running it by perlmonks, but no luck in progressing
> there.  I'm using Tk on Win32(XP) cygwin. I seem to have
> some odd interplay with "Tk" event handlers and
> ancestor searching.
>
> I have an Object Oriented hierarchy, with multiple packages in
> one file.  It's structured like using package names (from most Base
> to most Derived) of "ONE", "TWO" "THREE", and "FOUR",
> where each builds (has an @ISA relation) on the previous class.
> I'm setting up two event - handlers, both were in package THREE
> and was on my way to splitting the 2nd to class "FOUR" when
> unexpected errors prompted me to temporarily disable the 2nd event
> (timer) altogether.  The first is an event handler for all
> keys in TK (bound to a "main window").
>
> The symptom I'm running into is that I setup the "key_handler"
> in package THREE, pointing to a "keybd handler" (also in
> THREE).  According to the man page, the event (key)
> handler in package "THREE" is called using the form:
> "$main_window_blessed_reference -> Tk_Event_Handler ( \
>     <extra programmer specified arguments to be passed>)"
>
> The handler is "bound" to the "main_win" in a package "THREE"
> method.  The package THREE method is passed $s ($self) in the
> first param (as "normal").  It is the "one" handle that is
> opened in "main" for the life of the program (i.e. most
> derived class is a singleton).
>
> When I bind the event handler, I ask for 3 parameters to be passed
> to the handling function (in addition to the "main_win" handle it is
> called through): the "singleton" handle and 2 key-id values:
>
> sub __bind_events_to_main_win ($) {
>   my ($s,$main_win) = @_;
>   my $retval;
>   $retval = $main_win -> bind('<Any-KeyPress>' =>
>               [\&__handle_key, $s, Ev('A'), Ev('K')]);
> }
>
> The handler uses the stored "blessed singleton handle" in "$s" (self)
> as the base for future object references.  However, as soon
> as a level "THREE" package tries to call a method in an ancestral
> class, I get a Tk:Error message along the lines of
> "THREE::<ancestral-method not found>" -- it doesn't seem to be
> searching ancestral class TWO or ONE for "ancestral-method".
>
> The pointer ($s) passed to "handler" is of the same "class" (ref)
> as the level it was bound and called in (same levels).  When I
> call through the pointer (in the handler routine), I'd "expect"
> perl would (1) see the Class of the reference I am calling
> through, look in the symbol-table for that Class for "@ISA()"
> and follow the chain back to find Base classes, but that's not
> what it is doing.  It seems to not look through any Base
> classes.
>
> Stack traceback in debugger shows my handler routine called
> by a "Tk" "eval", don't know if that is related ('theoretically
> shouldn't be)...
> Another minor, but perhaps salient point, is that all the packages
> are in one (1) file.  The separation of routines into
> different classes/packages is more for grouping & ordering
> the objects/levels conceptually than it is to split it into
> several files (which would be a detraction, actually).
>
> It might be that I'm simply confused about what I am doing and
> shouldn't expect Base classes to be called through a blessed
> reference, except the debugger (perl -d script.pl) is as confused
> as I am.
>
> I use the 'm' command in debug and on the blessed reference
> I am calling through. The debugger prints out all the
> methods for the current class (THREE) and then lists
> available methods in classes(packages) TWO and then ONE.
> It seems that the debugger thinks I am calling through a
> class pointer with two ancestral classes -- but if I try to
> single step or continue, it goes off to Tk::Error with the Warning
> "THREE:<ancestral class in ONE or TWO not found>" at
> <breakpoint I just continued from> instead of passing control
> to the package ONE or package TWO method.
>
> As if to "accentuate" the breakdown of perl's OO method, if I
> want to call a method in an ancestral class, I can provide
> the same named method (in THREE) and chain the call with SUPER.
> But this is [obviously], a *hack* for debug/testing purposes.
>
> How can a call through a blessed reference "NOT" look through
> Base classes?
>
> Am sorta stuck at this point, -- if I have to manually add
> "proxy" routines in "THREE" to call the parental methods, that
> really defeats the purpose of going "OO", no?  It appears
> perl's OO mechanism isn't working as expected.  Why doesn't it
> auto search the Base classes at exec time when it *does* show
> the methods (in the Base classes TWO and ONE) in debug?
>
> Anyone have any ideas why this might be happening? (known bug in
> Tk, or OO, or whatever....?)

Disclaimer: Im not a Tk person in the slightest.

Its really hard from your description to say anything. Maybe TK is
being invoked before the class heirarchy you are working with is fully
defined and it is doing something like

  my $sub=$object->can('foo');

The fact that you say that you have a bunch of classes in a single
file suggests this is possible. Perl doesnt necessarily read and
compile a full file before executing any of its contents, in some
cases, such as with BEGIN or INIT blocks code is executed immediately
after it is recognized and before any further content in the file.

However there could be any number of reasons, maybe you spelled @ISA
incorrectly, maybe @isa instead, or whatever.

Anyway, the point is that Perls objected oriented method dispatch most
certainly does work. If it didnt every package that used Exporter (a
vast number) would fail. So would vast chunks of the published code
out there, not to mention most of the code used at my current company
and my previous company. Thus if there was an error of this sort its
highly likely that you wouldnt be the first one to report  it,
although its possible of course that somehow you have stumbled on some
bizzare edge case that nobody else has, its *extremely* unlikely.

Absent a small code snippet to demonstrate the problem its absolutely
impossible for us to identify what the problem is. The best we can do
is make vague suggestions and provide general guidance. In fact there
is one person on this list who used to like to respond to mails like
this with the response "i see it, the problem is on line 42" :-)

So please, first split up your class heriarchy into independent files,
use() them so they are forced to compile before any TK code executes,
and if the problem persists spend some time to produce a minimal
example of the problem and post it here or to Perlmonks or both.
Without code there really is nothing we can say beyond "Perl's OO
works just fine."

Cheers,
Yves




-- 
perl -Mre=debug -e "/just|another|perl|hacker/"

-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
Perl-Win32-GUI-Users mailing list
Perl-Win32-GUI-Users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/perl-win32-gui-users
http://perl-win32-gui.sourceforge.net/

Reply via email to