> -----Original Message-----
> From: Thomas, Mark - BLS CTR [mailto:[EMAIL PROTECTED]
> Sent: Thursday, April 03, 2003 3:01 PM
> To: [EMAIL PROTECTED]
> Subject: Perl OO Question: subclass using parent object's methods, not
> ove rridden methods?
> 
> 
> I have a module, let's call it My::Table, which represents a 
> data table. In
> order to simplify maintenance, I have separated output functions into
> subclasses called My::Table::HTML and My::Table::ASCII.
> 
> One would use the module like this:
> 
> use My::Table;
> $T = new My::Table;
> # here would be methods to fill the table with data
> $T->title("Test");
> # output the table
> $T->output('HTML');
> 
> Fairly standard stuff, except for the last line. The output() 
> method exec's
> the appropriate subclasses' output method. So in the above 
> output method,
> the method My::Table::HTML::output receives a My::Table 
> object. So far, so
> good. I have the following in My::Table::HTML:


Actually, not "so far so good."  This is why things aren't working properly
for you.  My::Table::HTML::output should be receiving a My::Table::HTML
object, not a My::Table object.  It's a subclass of My::Table.  So when you
call one of its methods, it should receive an object that is, at the same
time, an instance of both of those classes (through inheritance, of course).
 
> # this is an excerpt from My::Table::HTML
> use My::Table;
> @ISA=qw('My::Table');
> 
> sub output {
>       my $self = shift;
>       $self->dostuff();
> }
> 
> sub dostuff {
>       my $obj = shift;
>       #...
> }
> 
> Here's the problem: the dostuff() method only works if I 
> define the method
> in the parent, My::Table. It is not seen at all in My::Table::HTML. I
> thought that this was considered an "overridden method" and 
> perl would look
> for it in the subclass.

"Overridden" methods only apply to objects, and this PM file you just posted
is not an example of an object class.  If it were, it would have a
constructor that looked like this:

sub new {
        my($class, %attribs) = @_;
        my $self = {};
        return bless => $self;
}

But you have no constructor, so whatever object you're dealing with is NOT a
My::Table::HTML object, and thus doesn't have that method you are talking
about.
 
> I have a workaround. In the subclass I modified the output method as
> follows:
> sub output {
>       my $self = shift;
>       bless $self;    #why is this necessary?
>       $self->dostuff();
> }
> 
> But I don't know why it is necessary.

It's necessary because by calling "bless" you are doing what should have
been done in the missing object constructor I mentioned above.  You are
taking the reference and placing it in a different namespace (the
My::Table::HTML namespace).  Once you've done that, calls to the object will
search the new namespace for methods, and hence your dostuff() method is
discovered.

I think someone else mentioned that you are probably not really wanting a
subclass.  I believe he is correct.  It appears that you could probably be
working on something like this:

use My::Table;
$T = new My::Table;
# here would be methods to fill the table with data
$T->title("Test");
# output the table
$T->output('HTML');

# in package My::Table

sub output {
        my($self, $format_method) = @_;
        # this dynamically loads and instantiates the correct formatter
object.  If you pass in "HTML", you get a 
      #  My::Table::HTML object, etc.
        require "My/Table/" . $format_method . ".pm";
        my $formatter = "My::Table::$format_method"->new();  #note that the
formatter class must have a constructor named
                                                           #"new"
        $formatter->dostuff();
}

If you really want subclasses, you'll have to instantiate the specific
subclass you want _instead of_ the My::Table object each time.  The above
code provides a workaround that lets you decide which formatter to use at
runtime, instead at development time.  I hope I didn't make this too
confusing!

I really recommend you read the perltoot man page for more info on
subclassing.  It may help clear things up.  OO in Perl is great and powerful
stuff, but it's not as structured (i.e., _regimented_) as most other OO
languages, so it's easy to misunderstand what needs to be done.  In this
case, however, it appears to be a case of the wrong tool for the job.  A
subclass is not necessarily what you want.

jpt
_______________________________________________
Perl-Win32-Users mailing list
[EMAIL PROTECTED]
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs

Reply via email to